分类与扩展

  • 分类是什么

    分类是一种不需要继承即可给类添加方法的语法技术。可以在不改变原有类的前提下,动态地给这个类添加一些方法。

  • 使用场景

    1.给现有的类添加方法;

    2.将一个类的实现拆分成多个独立的源文件;

    3.声明私有的方法。

  • 优点

    a)可以减少单个文件的体积

    b)可以把不同的功能组织到不同的category里

    c)可以由多个开发者共同完成一个类

    d)可以按需加载想要的category 等等。

  • 注意事项

    a)分类中只能添加“方法”,不能增加成员变量。
    b)分类中可以访问原来类中的成员变量,但是只能访问@protect和@public形式的变量。如果想要访问本类中的私有变量,分类和子类一样,只能通过方法来访问。
    c)如果一定要在分类中添加成员变量,可以通过getter,setter手段进行添加

  • 如何使用
    这里写图片描述


  • 扩展是什么

类扩展(extension)是category的一个特例,有时候也被称为匿名分类。他的作用是为一个类添加一些私有的成员变量和方法。

其实我们经常使用到类扩展, 当我们创建一个新的控制器的时候 会出现下面的代码段 :

@interface STWebViewController ()//这就是类扩展的写法

@property (nonatomic, strong) UIWebView *webView;
- (void)setUrl;

@end

类扩展可以定义在.m文件中,这种扩展方式中定义的变量都是私有的,也可以定义在.h文件中,这样定义的代码就是共有的,类扩展在.m文件中声明私有方法是非常好的方式。不过类扩展中添加的新方法,一定要实现。categorygory中没有这种限制。


  • 拓展问题

a) 从上面内容了解到,分类只能添加方法。那么能不能添加成员变量呢,或者增加属性呢?

Object-c中,Category是不支持直接添加属性的,不过这不是很严谨,如果需要添加新的属性还是可以添加的,使用Runtime中的关联对象技术就可以实现。

还是先来了解一下,为什么分类不能添加成员变量吧 :

常规来说,在类中使用@property进行属性声明,编译器会自动生成getter和setter方法。但是在Category的指针结构体当中是没有属性列表的(ps : 指针结构体可以了解一下runtime机制,https://blog.csdn.net/jzl046/article/details/81389224),所以当你在Category中使用@property创建属性的时候编译器是不会帮你生成getter和setter方法,编译的时候不会出现问题,但是run了之后就会崩溃。

不过,由于OC是动态语言,方法真正的实现是通过runtime完成的,虽然系统不给我们生成setter/getter,但我们可以通过runtime手动添加setter/getter方法。

具体添加步骤如下 :

分类.h

#import "Programmer.h"

@interface Programmer (Category)

@property(nonatomic,copy) NSString *nameWithSetterGetter;           //设置setter/getter方法的属性

- (void) programCategoryMethod;                                     //分类方法

@end

分类.m

#import "Programmer+Category.h"
#import <objc/runtime.h>

static NSString *nameWithSetterGetterKey = @"nameWithSetterGetterKey"; @implementation Programmer (Category)

- (void)setNameWithSetterGetter:(NSString *)nameWithSetterGetter {
        objc_setAssociatedObject(self, &nameWithSetterGetterKey, nameWithSetterGetter, OBJC_ASSOCIATION_COPY); 
        }
- (NSString *)nameWithSetterGetter {
    return objc_getAssociatedObject(self, &nameWithSetterGetterKey); 
    }

- (void)programCategoryMethod {
    NSLog(@"实现分类方法"); 
    } 
    @end

这样就可以使用nameWithSetterGetter这个属性了

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值