11、runtime消息轉(zhuǎn)發(fā)機(jī)制
-
runtime的消息轉(zhuǎn)發(fā)流程圖
消息轉(zhuǎn)發(fā) -
消息轉(zhuǎn)發(fā)的示例
實(shí)現(xiàn) - 這里也給大家推薦一篇比較好的runtime文章。
12、runtime的方法交換&便利歸檔和解檔
- 方法交換實(shí)現(xiàn)
+ (void)swizzlingInClass:(Class)cls originalSelector:(SEL)originalSelector swizzledSelector:(SEL)swizzledSelector {
Class clzz = cls;
Method originalMethod = class_getInstanceMethod(clzz, originalSelector);
Method swizzMethod = class_getInstanceMethod(clzz, swizzledSelector);
BOOL didAddMethod = class_addMethod(clzz, originalSelector, method_getImplementation(swizzMethod), method_getTypeEncoding(swizzMethod));
if (didAddMethod) {
NSLog(@"replace方法成功");
class_replaceMethod(clzz, swizzledSelector, method_getImplementation(originalMethod), method_getTypeEncoding(originalMethod));
}
else {
NSLog(@"交換方法成功");
method_exchangeImplementations(originalMethod, swizzMethod);
}
}
- 自動(dòng)歸檔&解檔
- (void)encodeWithCoder:(NSCoder *)aCoder {
unsigned int count = 0;
Ivar *ivars = class_copyIvarList([People class], &count);
for (NSUInteger i = 0; i < count; i ++) {
Ivar ivar = ivars[i];
const char *name = ivar_getName(ivar);
NSString *key = [NSString stringWithUTF8String:name];
id value = [self valueForKey:key];
[aCoder encodeObject:value forKey:key];
}
free(ivars);
}
- (id)initWithCoder:(NSCoder *)aDecoder {
self = [super init];
if (self) {
unsigned int count = 0;
Ivar *ivars = class_copyIvarList([People class], &count);
for (NSUInteger i = 0; i < count; i ++) {
Ivar ivar = ivars[i];
const char *name = ivar_getName(ivar);
NSString *key = [NSString stringWithUTF8String:name];
id value = [aDecoder decodeObjectForKey:key];
[self setValue:value forKey:key];
}
free(ivars);
}
return self;
}
13、為自己創(chuàng)建的類提供全能初始化方法
- 不管類里面有多少個(gè)初始化方法,最終會(huì)指向一個(gè)全能初始化方法。
- 如果子類和父類的全能初始化方法不一樣,就要覆寫父類的初始化方法。
- 如果父類的初始化方法不適用于子類,需要把父類的初始化方法覆寫,然后拋出異常。
14、盡可能的實(shí)現(xiàn)description
方法
- 實(shí)現(xiàn)
description
方法,返回一個(gè)對(duì)該實(shí)例對(duì)象具有描述意義的字符串。
15、對(duì)象盡量為不可變
- 對(duì)象創(chuàng)建盡可能為不可變的。
- 對(duì)象對(duì)外暴露的屬性盡可能是
readonly
屬性,在對(duì)象內(nèi)部如果要進(jìn)行修改就在內(nèi)部把屬性修改成readwrite
屬性。
16、Objective-C里面的錯(cuò)誤處理
- 一般只會(huì)在發(fā)生嚴(yán)重錯(cuò)誤的時(shí)候才拋出異常,終止程序。
- 正常情況下我們只需要拋出普通的錯(cuò)誤信息,使程序能正常處理普通的錯(cuò)誤信息,而不至于讓程序崩潰。
17、NSCopying協(xié)議的理解
-
淺拷貝:只拷貝對(duì)象自身,底層的數(shù)據(jù)并不會(huì)進(jìn)行拷貝;深拷貝:對(duì)象自身和底層數(shù)據(jù)都進(jìn)行了一次拷貝。
淺拷貝和深拷貝區(qū)別 - 自定義對(duì)象如果要實(shí)現(xiàn)拷貝功能就需要實(shí)現(xiàn)NSCopying協(xié)議。
18、Objective-C里面的委托
- 委托的內(nèi)存修飾使用
weak
,委托的命名方式一般使用“駝峰命名”的方式進(jìn)行命名。 - 多次判斷委托方法是否實(shí)現(xiàn)可以使用flag進(jìn)行標(biāo)識(shí),以便不用多次進(jìn)行判斷。
19、“大類”通過分類的方式進(jìn)行切割
- 使用分類進(jìn)行進(jìn)行類功能模塊的分割,使每個(gè)分類都是一個(gè)小的功能模塊。
- 使用分類機(jī)制隱藏不需要公開的使用方法。
20、第三方分類的管理
- 盡量為第三方分類添加專用前綴。
- 盡量為第三方分類里面的方法添加專用的前綴。