iOS之 Category 属性 的理解

在 Objective-C 中可以通过 Category 给一个现有的类添加属性,但是却不能添加实例变量

反正读第一遍的时候我是有点晕的,可以添加“属性”,然后又说“添加实例变量”,第一感觉就好像 有点自相矛盾了。那么我们谈谈:

  • 什么是实例变量?

    实例变量就是一种变量,可以存放数据的。在oc上,形式就如:        

@interface MyViewController :UIViewController
{
    UIButton *myButton;
}

@end
  • 什么是属性?

  属性是oc的一个新的机制,并且要求你必须声明与之对应的实例变量,这是最早期的一种概念,随着编译器从GCC转换为LLVM(low level virtual machine),从此不再需要为属性声明实例变量了,如果LLVM发现一个没有匹配实例变量的属性,它将自动创建一个以下划线开头的实例变量。

  • Category可以给一个现有的类添加属性

我建立了个 UIColor的hex分类  ,在UIColor+hex.h上我做了这么一件事:

然后做你会发现编译器并不会报任何错误,build一下也不会有问题,当然这不能说这段代码是可以运行的【crash】。仔细的话,你会发现在.m中是有警告的。

它说,属性 hex的setHex和hex方法需要定义使用 @dynamic或者自己实现。  这里添加的属性,不会自动生成实例变量,这里添加的属性其实是添加的getter与setter方法。

这里,我们是不是可以理解上面的那句话了,其实就是等同于这句话

类别中只能添加方法,不能添加实例变量

 

首先,我们就用了@dynamic去做:

警告确实立马消失,但是是不是可以运行了呢?梦想是美好的,结果依旧crash。

  • 那么这个@dynamic到底干了什么可以让警告消除,当然你会不会发现这个@dynamic在哪里见过?对了在你用coredata的时候,你就会发现了【NSManagedObject自己探索去吧】。

       @dynamic 是相对于 @synthesize的,它们用样用于修饰 @property,用于生成对应的的getter和setter方法。但是@ dynamic表示这个成员变量的getter和setter方法并不是直接由编译器生成,而是手工生成或者运行时生成。

@dynamic just tells the compiler that the getter and setter methods are implemented not by the class itself but somewhere else (like the superclass or will be provided at runtime).

  那为什么会崩溃?哈哈,不要想当然了,因为你没有在runtime中提供getter and setter methods。那当然会崩溃啦。

 

上面我们就基本上了解了在category添加属性的一些问题。那么该如何解决这些问题,也是下面我想说的Associated Objects,let's  go!

首先我们带着这么2个疑问:

  1. 关联对象被存放到什么地方,是不是存放在被关联对象本身的内存中?
  2. 关联对象的生命周期怎么样。什么时候被释放,什么时候被移除?

 

上面是两种方法的实现

  • objc_setAssociatedObject
  • objc_getAssociatedObject
  • objc_removeAssociatedObjects

其中第三个函数objc_removeAssociatedObjects 函数我们一般式用不上的,因为这个函数会移除一个对象的所有关联对象,该将对象恢复为“

pristine state”。一般我我没问你如果要移除一个关联对象,我们会使用objc_setAssociatedObject 函数中传入nil就可以移除。

 

  • 你会发现这两个函数都有一个key,在关联对象的时候我们使用了两种形式,那么这个key的设置有什么要求么?

  key 值必须是一个对象级别的唯一常量

    从上面的两种实现关联对象的方法中,我们使用了两种不同的key值

  1. static void *kAssociatedObjectKey = &kAssociatedObjectKey;
  2. selector ,使用 getter 方法的名称作为 key 值。

  3. 其实还有一种 static char kAssociatedObjectKey;      objc_getAssociatedObject(self, &kAssociatedObjectKey);

  对比这三种方式,很多人都喜欢第二种

 

  • 关于这个 objc_AssociationPolicy(关联策略)又是什么?

  

关联策略

等价属性

说明

OBJC_ASSOCIATION_ASSIGN

@property (assign) or @property (unsafe_unretained)

弱引用关联对象

OBJC_ASSOCIATION_RETAIN_NONATOMIC

@property (strong, nonatomic)

强引用关联对象,且为非原子操作

OBJC_ASSOCIATION_COPY_NONATOMIC

@property (copy, nonatomic)

复制关联对象,且为非原子操作

OBJC_ASSOCIATION_RETAIN

@property (strong, atomic)

强引用关联对象,且为原子操作

OBJC_ASSOCIATION_COPY

@property (copy, atomic)

复制关联对象,且为原子操作

  上面这张表很清晰的告诉你这个关联策略的作用。

  1. 关联对象与被关联对象本身的存储并没有直接的关系,它是存储在单独的哈希表中的;
  2. 关联对象的五种关联策略与属性的限定符非常类似,在绝大多数情况下,我们都会使用 OBJC_ASSOCIATION_RETAIN_NONATOMIC 的关联策略,这可以保证我们持有关联对象;
  3. 关联对象的释放时机与移除时机并不总是一致,比如实验中用关联策略 OBJC_ASSOCIATION_ASSIGN 进行关联的对象,很早就已经被释放了,但是并没有被移除,而再使用这个关联对象时就会造成 Crash 。

 

 

转载于:https://www.cnblogs.com/Ohero/p/4739089.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
【优质项目推荐】 1、项目代码均经过严格本地测试,运行OK,确保功能稳定后才上传平台。可放心下载并立即投入使用,若遇到任何使用问题,随时欢迎私信反馈与沟通,博主会第一时间回复。 2、项目适用于计算机相关专业(如计科、信息安全、数据科学、人工智能、通信、物联网、自动化、电子信息等)的在校学生、专业教师,或企业员工,小白入门等都适用。 3、该项目不仅具有很高的学习借鉴价值,对于初学者来说,也是入门进阶的绝佳选择;当然也可以直接用于 毕设、课设、期末大作业或项目初期立项演示等。 3、开放创新:如果您有一定基础,且热爱探索钻研,可以在此代码基础上二次开发,进行修改、扩展,创造出属于自己的独特应用。 欢迎下载使用优质资源!欢迎借鉴使用,并欢迎学习交流,共同探索编程的无穷魅力! 基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip 基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip 基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip
提供的源码资源涵盖了安卓应用、小程序、Python应用和Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值