2-1 OC 类别(分类)

Posted weiboyuan

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了2-1 OC 类别(分类)相关的知识,希望对你有一定的参考价值。

一、类别的作用

1.声明私有方法。

2.分解体积庞大的类文件。

3.把Framework私有方法公开。

 

二、类别的特点

1.运行时决议。

2.可以为系统类添加类别。(区别于扩展)

 

三、类别中可以添加什么

1.实例方法。

2.类方法。

3.协议。

4.属性。

类别并不是不可以扩展属性的,只不过类别中不可以直接添加成员变量(实例变量)而已(第5点解决该问题)。

在类别中为属性添加set/get方法,在set方法里面赋值的时候找不到赋值的对象,也就是说系统没有为我们生成带下划线的成员变量,没生成我们就自己加,一加就报错,这才是类别不能扩展属性的根本原因。

5.实例变量(通过关联对象可以添加)。

//UINavigationController+Cloudox.h文件
#import <UIKit/UIKit.h>

@interface UINavigationController (Cloudox)

@property (copy, nonatomic) NSString *cloudox;

@end

//UINavigationController+Cloudox.m文件
#import "UINavigationController+Cloudox.h"
#import <objc/runtime.h>

@implementation UINavigationController (Cloudox)

//定义常量 必须是C语言字符串
static char *CloudoxKey = "CloudoxKey";

-(void)setCloudox:(NSString *)cloudox{
    /*
     objc_AssociationPolicy参数使用的策略:
     OBJC_ASSOCIATION_ASSIGN;            //assign策略
     OBJC_ASSOCIATION_COPY_NONATOMIC;    //copy策略
     OBJC_ASSOCIATION_RETAIN_NONATOMIC;  // retain策略

     OBJC_ASSOCIATION_RETAIN;
     OBJC_ASSOCIATION_COPY;
     */
    /*
     关联方法:
     objc_setAssociatedObject(id object, const void *key, id value, objc_AssociationPolicy policy);

     参数:
     * id object 给哪个对象的属性赋值
     const void *key 属性对应的key
     id value  设置属性值为value
     objc_AssociationPolicy policy  使用的策略,是一个枚举值,和copy,retain,assign是一样的,手机开发一般都选择NONATOMIC
     */

    objc_setAssociatedObject(self, CloudoxKey, cloudox, OBJC_ASSOCIATION_COPY_NONATOMIC);
}

-(NSString *)cloudox{
    return objc_getAssociatedObject(self, CloudoxKey);
}


@end

 

四、加载调用栈

以方法为例:分类数组里有方法数组(二维数组),将类别方法拼接到原类的方法列表中实现如下:

1.总数 = 旧+新。

2.内存分配新总数(调整Array的存储)。

3.设置新总数。

4.memmove操作(Array结构):【【】,【】,【】,【原有方法列表一】,【原油方法列表二】】。

5.memcpy内存拷贝(Array结构):【【新A类别方法列表】,【新B类别方法列表】,【新C类别方法列表】,【原有方法列表一】,【原油方法列表二】】。

注意1:同一个类的两个分类有同名方法哪个生效?

答:最后编译的分类的方法生效(原因:调取方法列表倒序调用)。

注意2:分类“覆盖”(不是替换,方法都会保留)原有宿主类方法,由于分类方法被放到前面所以会出现这种情况,即分类方法优先被实现。

注意3:名字相同的分类会编译报错。

以上是关于2-1 OC 类别(分类)的主要内容,如果未能解决你的问题,请参考以下文章

31-oc分类和类扩展

OC中类别(Category)的属性

IOS开发-OC学习-常用功能代码片段整理

OC基础回想类别

无法访问 Swift 子类中的 oc 类别方法

IOS(六) 分类Category