分類(lèi)不能定義屬性只能定義方法 , 是因?yàn)閷?duì)象創(chuàng)建的過(guò)程中已經(jīng)alloc過(guò)了,你這個(gè)對(duì)象有多少屬性已經(jīng)固定了不能在改變了,而方法與屬性的區(qū)別在于方法是一個(gè)二級(jí)鏈表 , 他可以到運(yùn)行時(shí)再去決定方法列表的最終情況所以分類(lèi)當(dāng)中不能定義屬性卻可以定義方法,就是因?yàn)橛辛诉\(yùn)行時(shí)的存在 , 所以這里就可以同樣用運(yùn)行時(shí)的處理辦法讓屬性列表的最終確定推遲到運(yùn)行時(shí)再去決定!這個(gè)方法的名字叫做
動(dòng)態(tài)綁定
或關(guān)聯(lián)對(duì)象
!!!
在這里我們先看看如果不用運(yùn)行時(shí)
動(dòng)態(tài)綁定 , 關(guān)聯(lián)對(duì)象
的方法該怎么去確定:
NSArray+ArrayName.h文件
給NSArray添加一個(gè)ArrayName的屬性:
#import <Foundation/Foundation.h>
@interface NSArray (ArrayName)
@property (nonatomic , copy) NSString *name ;
@end
NSArray+ArrayName.m文件
#import "NSArray+ArrayName.h"
//我們的方法是這樣的:
//找一個(gè)全局的靜態(tài)變量去存儲(chǔ)這個(gè)name屬性:
//首先創(chuàng)建一個(gè)可變字典
static NSMutableDictionary *kArrayToName ;
@implementation NSArray (ArrayName)
//初始化這個(gè)可變字典:
- (void)initArrayToName {
if (kArrayToName == nil) {
kArrayToName = [NSMutableDictionary dictionary] ;
}
}
#pragma mark - 重寫(xiě)getter方法
- (NSString *)name {
[self initArrayToName] ;
//取值的時(shí)候強(qiáng)制把內(nèi)存地址改成一個(gè)數(shù)字 , 并用@()語(yǔ)法糖包裝成NSNumber對(duì)象:
return kArrayToName[@((NSInteger)self)] ;
}
#pragma mark - 重寫(xiě)setter方法
- (void)setName:(NSString *)name {
[self initArrayToName] ;
kArrayToName[@((NSInteger)self)] = name ;
}
@end
接下來(lái)我們?cè)倏匆豢磩?dòng)態(tài)綁定的方法:
//定義一個(gè)全局的key:
//創(chuàng)建一個(gè)唯一的一個(gè)內(nèi)存地址,創(chuàng)建一個(gè)static的靜態(tài)變量 , 他的類(lèi)型是void的指針類(lèi)型 ;
//因?yàn)?static 修飾的變量的內(nèi)存地址是唯一的!!!
static void *kArrayNameKey = &kArrayNameKey ;
//也可以寫(xiě)為:static void *kArrayNameKey ; 后面的取地址符&目的就是讓本地址是唯一的,實(shí)際上你取值只要是唯一的就行!為了方便這里的一個(gè)小技巧就是取自己這個(gè)指針變量的的內(nèi)存地址 ;
@implementation NSArray (ArrayName)
#pragma mark - 重寫(xiě)getter方法
- (NSString *)name {
return objc_getAssociatedObject(self, kArrayNameKey) ;
}
#pragma mark - 重寫(xiě)setter方法
-(void)setName:(NSString *)name {
objc_setAssociatedObject(self, kArrayNameKey, name, OBJC_ASSOCIATION_COPY_NONATOMIC) ;
}
@end
OBJC_ENUM枚舉值
其實(shí)是與@property是類(lèi)似的,從這里我們更能看出來(lái)
Objective - C語(yǔ)言
對(duì)C語(yǔ)言
的這一層面向?qū)ο?/code>的封裝外衣!
typedef OBJC_ENUM(uintptr_t, objc_AssociationPolicy) {
OBJC_ASSOCIATION_ASSIGN = 0, /**< Specifies a weak reference to the associated object. */
OBJC_ASSOCIATION_RETAIN_NONATOMIC = 1, /**< Specifies a strong reference to the associated object.
* The association is not made atomically. */
OBJC_ASSOCIATION_COPY_NONATOMIC = 3, /**< Specifies that the associated object is copied.
* The association is not made atomically. */
OBJC_ASSOCIATION_RETAIN = 01401, /**< Specifies a strong reference to the associated object.
* The association is made atomically. */
OBJC_ASSOCIATION_COPY = 01403 /**< Specifies that the associated object is copied.
* The association is made atomically. */
};