本文總結參考書籍《Effective Objective-C2.0(編寫高質量iOS與OS X代碼的52個方法總結》,詳細內容可購買該書籍或者下載電子版。
1.在類的頭文件中盡量少引入其他頭文件
在需要的地方可以使用向前聲明@class告訴編譯器XX是個類名,然后在實現文件中再引入頭文件。可以避免不必要的引入,減少編譯時間。向前聲明也能解決兩個類相互引用的問題。
2.多用字面量語法,少用與之等價的方法
//例如:
NSNumber *number = [NSNumber numberWithInt:1];
NSNumber *number = @1;//推薦
使用字面量語法可以縮減代碼的長度,更為易讀。 NSString,NSArray,NSDictionary等。通過這種方法創建的對象都是不可變的。注:值不能為nil,不然會拋出異常。
3.多用類型常量,少用#define預處理指令
#define ANIMATION_DURATION 0.3
使用預處理指令的缺點:
1.該常量沒有類型信息,降低了可讀性
2.若定義在頭文件,引入了頭文件的地方ANIMATION_DURATION都會被替換
推薦:
static const NSTimeInterval kAnimationDuration = 0.3;
1.在實現文件中使用static const定義。
2.在頭文件中推薦使用extern來聲明全局常量。
4.用枚舉表示狀態、選項、狀態碼
1.可增加狀態的可讀性;
2.NS_ENUM 定義可指定底層數據類型;
3.在用枚舉類型處理switch語句時,不要實現default分支。
5.對象等同性
比較NSString時,推薦使用 isEqualToString。 NSNumber推薦使用 isEqualToNumber
6.對外提供接口時,盡量提供全能的初始化方法
7.實現description方法
//例如:
- (NSString *)description {
return [NSString stringWithFormat:@"%@/%@",[self class],_name];
}
使用description方法可以返回一個有意義的字符串,方便調試查看
8.將類的實現代碼分散到數個分類中
使用分類機制把類的實現代碼劃分成易于管理的小塊,可以避免實現文件中因方法過多造成的龐大。
9.總為第三方類的分類名稱加前綴
避免分類名中出現相同的方法名,更被覆蓋。
10.通過Dispatch Group機制,根據系統資源狀況來執行任務
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_group_t dispathGroup = dispatch_group_create();
dispatch_group_async(dispathGroup,queue , ^{
//do something
});
11.對用塊枚舉,時候用for循環
[arr enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
}];
除此之外還有一些列的類似遍歷方法。技能獲取到對象,也能知道下標,還提供了參數用于終止遍歷。
12.構建緩存時,選用NSCache而非NSDictionary
使用NSCache在系統資源將耗盡的時候,會自動刪減緩存,是線程安全的。
13.NSTimer循環引用問題
1.NSTimer對象會保留其目標對象,直到計時器本身失效。調用 invalidate方法可讓計時器失效。一次性的計時器觸發后也會失效。
2.反復執行任務的計時器,計時器的目標對象又保留了計時器本身,會造成循環引用問題。
3.可以為NSTimer擴充方法,使用代碼塊來打破循環引用。主要方法是改變NSTimer的target,讓NSTimer成為自己的Target。
@implementation NSTimer (weakTarget)
+ (NSTimer *)xy_scheduledTimerWithTimeInterval:(NSTimeInterval)interval
block:(void(^)())block
repeats:(BOOL)repeats {
return [self scheduledTimerWithTimeInterval:interval
target:self
selector:@selector(xy_blockInvoke:)
userInfo:[block copy]
repeats:repeats];
}
+ (void)xy_blockInvoke:(NSTimer *)timer {
void (^block)() = timer.userInfo;
if(block) {
block();
}
}
@end