最近再次拜讀了<
>這本書, 經典的書確實值得閱讀, 而且裏面的不少東西, 並不過期, 書中有52條建議, 但這裏筆者只是選取了其中的幾條來分享, 這幾條多是咱們在開發中比較經常使用的, 還有就是由於其餘的不是能用很短的語言寫出來的, 若是你沒有讀過這本經典的書, 仍是建議閱讀一下原書. objective-c
NSObject *obj1 = [NSObject new];
, obj1這個指針變量是分配在棧上的, 他指向的是這一個分配在堆上面的實例對象, 若是進行下面的賦值操做NSObject *obj2 = obj1;
,那麼並無新生成一個實例對象, 只是在棧上分配了一個新的指針變量obj2, 而obj2和obj1指向的實例對象是同一個.A.h
文件中引入其餘的B.h
文件, 由於在別人引入A.h
的時候, 同時也引入了B.h
文件, 增長沒必要要的文件耦合和編譯時間, 通常在.h
文件中使用前向聲明
即 @class B
, 而在.m文件中才真的引入頭文件, 固然對於protocol不能使用前向聲明, 若是將protocol放在了另外一個.h文件中, 那麼就必需要引入這個頭文件了.語法糖
, 使用它可讓代碼可讀性更高, 固然對於一些必需要使用到初始化方法的時候字面量語法就很差用了.例如:NSString *str = @"string";
NSArray *arr = @[obj1, obj2];
arr[1]// 讀取使用下標而儘可能不使用對應的函數...
[array setObject:<#(nonnull id)#=""> atIndexedSubscript:<#(nsuinteger)#>]
複製代碼
const
, static
, extern
相結合來定義常量/// 使用static 和const 定義文件內部的常量 通常使用k開頭命名
static float const kAnimationTime = 2.0f;
/// 使用const定義全局的常量, 在其餘文件中能夠經過 extern float const kAnimationTime引入使用, 通常不用k開頭命名, 而使用class名字
float const CustomAnimationTime = 2.0f;複製代碼
1. 定義一個整形變量, 而後說明, 不一樣的整數表明不一樣的狀態, 那麼這樣對於開發就很不方便, 必須得很清楚而且很正確的輸入對應的整數才能表示相應的狀態, 那麼就很容易出錯, 和不便於維護
int statusCode;
if (statusCode == 200) { }/// 請求成功
else if () ....
2. 使用枚舉, 對不一樣的狀態定義不一樣的名字, 這樣就很清晰方便了, 固然定義的時候使用NS_ENUM比使用enum要`好`
typedef NS_ENUM(NSInteger, ErrorCode) {
ErrorCodeNotFind,
ErrorCodeLostConnection,
ErrorCodeUnknow
};複製代碼
顯然上面你應該選用枚舉, 同時還有一種狀況就是, 定義多選項
, 這個你是會把他們都放進一個數組中麼?? 固然不要這樣作, 這個時候也應該使用枚舉來定義, 不過會有一點的小技巧, Apple對這種進行了一個包裝, 使用NS_OPTIONS
而不是enum
typedef NS_OPTIONS(NSInteger, ErrorOptions) {
ErrorOptionsNone = 0,
ErrorOptionsOne = 1 << 0, ///左移操做 --- 1 --- 0001
ErrorOptionsTwo = 1 << 1, --- 2 --- 0010
ErrorOptionsThree = 1 << 2 --- 4 --- 0100
};複製代碼
由於上面定義的枚舉值都爲2的整數次冪值, 因此後面就可使用位操做符 與(&)和或(|)來進行選項的篩選ErrorOptions options = ErrorOptionsOne | ErrorOptionsTwo; //--- 0011
if (options & ErrorOptionsOne) {// ErrorOptionsOne
// 結束判斷後面
}
else if (options & ErrorOptionsTwo) {// ErrorOptionsTwo
// ...
}
else {
// ...
}複製代碼
脆弱
的, 有可能使用的class尚未被加載到系統中來, 固然使用Foundation裏面的NSString...這些是沒有問題的ZJChildClass類裏面沒有重寫initialize方法, 可是他的父類重寫了, 因此在初始化ZJChildClass的時候, 父類的initialize會被調用兩次, 即會打印兩條
@interface ZJBaseClass : NSObject
@end
@implementation ZJBaseClass
+ (void)initialize {
NSLog(@"加載一次-----");
}
@end
@interface ZJChildClass : ZJBaseClass
@end複製代碼
因此通常都是這樣來重寫initialize方法的, 保證只會像咱們指望的那樣調用
一次+ (void)initialize {
if (self == [ZJBaseClass class]) { /// 不能用 [self class]
NSLog(@"加載一次-----");
}
}複製代碼
dispatch_once
, 這樣能夠保證線程安全
, 而且只執行一次, 最多見的是用來實現單例+ (instancetype)sharedInstance {
static Object *sharedInstance = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sharedInstance = [self new];
});
return sharedInstance;
}複製代碼