分类不能定义属性只能定义方法 , 是因为对象创建的过程中已经alloc过了,你这个对象有多少属性已经固定了不能在改变了,而方法与属性的区别在于方法是一个二级链表 , 他可以到运行时再去决定方法列表的最终情况所以分类当中不能定义属性却可以定义方法,就是因为有了运行时的存在 , 所以这里就可以同样用运行时的处理办法让属性列表的最终确定推迟到运行时再去决定!这个方法的名字叫做
动态绑定
或关联对象
!!!
在这里我们先看看如果不用运行时
动态绑定 , 关联对象
的方法该怎么去确定:
NSArray+ArrayName.h文件
给NSArray添加一个ArrayName的属性:
#import <Foundation/Foundation.h>
@interface NSArray (ArrayName)
@property (nonatomic , copy) NSString *name ;
@end
NSArray+ArrayName.m文件
#import "NSArray+ArrayName.h"
//我们的方法是这样的:
//找一个全局的静态变量去存储这个name属性:
//首先创建一个可变字典
static NSMutableDictionary *kArrayToName ;
@implementation NSArray (ArrayName)
//初始化这个可变字典:
- (void)initArrayToName {
if (kArrayToName == nil) {
kArrayToName = [NSMutableDictionary dictionary] ;
}
}
#pragma mark - 重写getter方法
- (NSString *)name {
[self initArrayToName] ;
//取值的时候强制把内存地址改成一个数字 , 并用@()语法糖包装成NSNumber对象:
return kArrayToName[@((NSInteger)self)] ;
}
#pragma mark - 重写setter方法
- (void)setName:(NSString *)name {
[self initArrayToName] ;
kArrayToName[@((NSInteger)self)] = name ;
}
@end
接下来我们再看一看动态绑定的方法:
//定义一个全局的key:
//创建一个唯一的一个内存地址,创建一个static的静态变量 , 他的类型是void的指针类型 ;
//因为:static 修饰的变量的内存地址是唯一的!!!
static void *kArrayNameKey = &kArrayNameKey ;
//也可以写为:static void *kArrayNameKey ; 后面的取地址符&目的就是让本地址是唯一的,实际上你取值只要是唯一的就行!为了方便这里的一个小技巧就是取自己这个指针变量的的内存地址 ;
@implementation NSArray (ArrayName)
#pragma mark - 重写getter方法
- (NSString *)name {
return objc_getAssociatedObject(self, kArrayNameKey) ;
}
#pragma mark - 重写setter方法
-(void)setName:(NSString *)name {
objc_setAssociatedObject(self, kArrayNameKey, name, OBJC_ASSOCIATION_COPY_NONATOMIC) ;
}
@end
OBJC_ENUM枚举值
其实是与@property是类似的,从这里我们更能看出来
Objective - C语言
对C语言
的这一层面向对象
的封装外衣!
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. */
};
网友评论