在分类当中定义属性的方法

2017-04-20  本文已影响35人  小苗晓雪

分类不能定义属性只能定义方法 , 是因为对象创建的过程中已经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. */
};

愿编程让这个世界更美好

上一篇 下一篇

猜你喜欢

热点阅读