美文网首页
在分类当中定义属性的方法

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

作者: 小苗晓雪 | 来源:发表于2017-04-20 21:27 被阅读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. */
};

愿编程让这个世界更美好

相关文章

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

    分类不能定义属性只能定义方法 , 是因为对象创建的过程中已经alloc过了,你这个对象有多少属性已经固定了不能在改...

  • 在分类中定义属性问题的简要分析

    我们都知道在分类中不能定义属性 , 分类就是给本类扩充方法用的 , 但是如果非要在分类中定义属性 , 如果什么都不...

  • 面试中解释下类别,原理

    1、分类的定义 分类的本质是一个结构体,存储类的实例方法、类方法、协议、实例属性、类属性。 2、分类的特点和作用 ...

  • 关于Category关联属性

    关联属性的相关方法及优缺点 方法1 在分类中定义全局参数接收。 通过赋值打印,可以得出理想结果。但是,如果其他对象...

  • 关联对象-给Category添加属性

    我们知道,分类无法添加成员变量,在分类中定义了属性,系统没有生成对应的成员变量,也没有实现set和get方法。那我...

  • iOS - 关联对象Association

    上周写了篇关于iOS 分类的文章,我们可以在分类中定义属性,但只是定义了属性,编译器既没有生成相应的setter和...

  • 动态添加属性

    动态向类中加入属性 (未实现的方法并没有在类的MethodList)在分类中只能添加方法,不能添加属性,在分类中声...

  • 如何给 Category 添加属性?关联对象以什么形式进行存储?

    分类无法添加成员变量,在分类中定义了属性,系统没有生成对应的成员变量,也没有实现set和get方法。那我们如何实现...

  • 看书笔记26-30

    二十六:勿在分类中声明属性 把封装数据所用的全部属性都定义在主接口里。在"class-continuation分类...

  • Procotol 和 Delegate

    目录 Procotol 协议的概念 协议的分类 协议的定义 协议的遵循 协议的方法 协议的属性 Delegate ...

网友评论

      本文标题:在分类当中定义属性的方法

      本文链接:https://www.haomeiwen.com/subject/oyfrzttx.html