概述: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