概述:Objective-C中的分类是修饰模式的一种具体实现,主要做用是在不改变原有类的基础上,动态的为类扩展功能(添加方法)。git
分类的优势github
运行时在处理分类时会倒序遍历分类数组,最早访问最后编译的类,最后编译的类的同名方法最终生效。数组
下面咱们来看看源码解析:app
int mcount = 0; // 记录方法的数量
int propcount = 0; // 记录属性的数量
int protocount = 0; // 记录协议的数量
int i = cats->count; // 获取分类个数
bool fromBundle = NO; // 记录是不是从 bundle 中取的
while (i--) { // 从后往前遍历,保证先取最后编译的类
auto&;
entry = cats->list[i]; // 分类,locstamped_category_t 类型
// 取出分类中的方法列表;若是是元类,取得的是类方法列表;不然取得的是实例方法列表
method_list_t *mlist = entry.cat->methodsForMeta(isMeta);
if (mlist) {
mlists[mcount++] = mlist; // 将方法列表放入 mlists 方法列表数组中
fromBundle |= entry.hi->isBundle(); // 分类的头部信息中存储了是不是 bundle,将其记住
}
// 取出分类中的属性列表,若是是元类,取得是nil
property_list_t *proplist = entry.cat->propertiesForMeta(isMeta);
if (proplist) {
proplists[propcount++] = proplist; // 将属性列表放入 proplists 属性列表数组中
}
// 取出分类中遵循的协议列表
protocol_list_t *protolist = entry.cat->protocols;
if (protolist) {
protolists[protocount++] = protolist; // 将协议列表放入 protolists 协议列表数组中
}
}
复制代码
NSArray *array = [NSArray array];
//相同地址
NSLog(@"%p",array);
NSLog(@"%p",[array copy]);
// __NSArray0 (不可变数组)
NSLog(@"%@",NSStringFromClass([[array copy] class]));
复制代码
输出: 性能
NSMutableArray *mutArray = [NSMutableArray array];
//输出不一样地址
NSLog(@"%p",mutArray);
NSLog(@"%p",[mutArray mutableCopy]);
// __NSArrayM (可变数组)
NSLog(@"%@",NSStringFromClass([[mutArray mutableCopy] class]));
复制代码
输出: ui
NSMutableArray *mutArray = [NSMutableArray array];
//不一样地址
NSLog(@"%p",mutArray);
NSLog(@"%p",[mutArray copy]);
// __NSArray0
NSLog(@"%@",NSStringFromClass([[mutArray copy] class]));
复制代码
输出: atom
NSArray *array = [NSArray array];
//不一样对象
NSLog(@"%p",array);
NSLog(@"%p",[array mutableCopy]);
// __NSArrayM
NSLog(@"%@",NSStringFromClass([[array mutableCopy] class]));
复制代码
输出: spa
除不可变对象的不可变拷贝为浅拷贝,其他都是深拷贝 3d
-(void)willChangeValueForKey:(NSString *)key;
-(void)didChangeValueForKey:(NSString *)key;
复制代码
#import "SingletonSample.h"
@interface SingletonSample()<NSCopying>
@end
@implementation SingletonSample
+(instancetype)sharedInstance
{
static SingletonSample *instance = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
instance = [[super allocWithZone:NULL] init];
});
return instance;
}
+(instancetype)allocWithZone:(struct _NSZone *)zone
{
return [self sharedInstance];
}
-(id)copyWithZone:(NSZone *)zone
{
return self;
}
@end
复制代码
本篇相关代码指针
邮箱: adrenine@163.com
邮箱: holaux@gmail.com
邮箱: ledahapple@icloud.com