第1條:oc起源
oc是給c添加面向對象特性,是其超集
oc使用動態綁定的消息結構,運行期所執行代碼由運行環境決定,非編譯器決定。函數調用由編譯器決定。
-
oc指針用來指示對象。
NSString* someString=@"the string" 此變量為指向NSString的指針
-
對象所占內存分配在堆上,oc的內存管理是指對堆空間的內存管理。不帶*號的變量,不是對象,保存在棧上(基本數據類型)。
CoreGraphics中的CGRect,CGRect是C結構體。 struct CGRect{ CGPoint origin; CGSize size; }; typedef struct CGRect CGRect;
第2條:在類的頭文件中盡量少引入其他頭文件
-
@class引用,避免循環引用
#import <Foundation/Foundation.h> @class EOCEmployer; @interface Employee : NSObject @property(nonatomic,copy)NSString *name; @property(nonatomic,strong)EOCEmployer *employer; @end
第3條:多用字面量語法,少用與之等價的方法
-
字面數值
//非字面量創建 NSNumber *num=[NSNumber numberWithInt:1]; //字面量創建 NSNumber *intNum=@1; NSNumber *boolNum=@YES; NSNumber *charNum=@'a'; int x=5; float y=5.67; NSNumber *totoalNum=@(x*y);
-
字面量數組
//非字面量 NSArray *array=[NSArray arrayWithObjects:@"1",@"2",@"3",@"4", nil]; NSString *one=[array objectAtIndex:1]; //字面量 NSArray *array=@[@"1",@"2",@"3",@"4"]; NSString *one= array[1];
-
字面量字典
//非字面量 NSDictionary *person=[NSDictionary dictionaryWithObjectsAndKeys:@"Mat",@"name",[NSNumber numberWithInt:20],@"age", nil]; NSString *name=[person objectForKey:@"name"]; //字面量 NSDictionary *person=@{@"name":@"Mat",@"age":@28}; NSString *name=person[@"name"];
可變數組與字典
NSMutableArray *mutableArray=[array mutableCopy];
//非字面量
[mutableArray replaceObjectAtIndex:1 withObject:@"a"];
//字面量
mutableArray[1]=@"a";
NSMutableDictionary *mutableDic=[person mutableCopy];
//非字面量
[mutableDic setObject:@"MO" forKey:@"name"];
//字面量
mutableDic[@"name"]=@"MO";
第4條:多用類型常量,少用#define預處理指令
不要用#define定義常量,這樣定義出來的常量不含類型信息。
使用static const 定義“只在編譯單元內可見的常量”,此類常量不在全局符號表中,無需加前綴。
-
在頭文件中使用extern來聲明全局常量,需要加前綴。
static const NSTimeInterval kAnimationDuration=0.3; 在頭文件中 extern NSString *const kAnimationDuration;
第5條:用枚舉表示狀態、選項、狀態碼
第6條:理解“屬性”
- 點語法就是對存取方法的調用
- @dynamic關鍵字,告訴編譯器不要自動創建實例變量和存取方法
- 特性:atomic(原子性)、nonatomic、readwrite、readonly、assign(純量類型:基本數據類型、NSInteger、CGFloat等)、strong(擁有關系:保留新值,釋放舊值,再設新值)、weak(非擁有關系:不設置新值、不釋放舊值,對象釋放就清空)、unsafe_unretained(語義與assign相同,適用于對象類型,非擁有關系,對象摧毀時,屬性值不會自動清空)、copy、getter=<name>、setter=<name>
第7條:在對象內部盡量直接訪問實例變量
- 直接訪問實例變量會比點語法的速度快,因為不經過方法派發。
- 直接訪問實例變量,不會調用其設置方法,繞過了內存管理。
- 直接訪問實例變量,不會觸發KVO。
- 通過屬性訪問有助于排查與之相關的錯誤,因為可以在存取方法里設置斷點,監控屬性的調用者和時機。
- 讀取時用實例變量讀,寫入時用屬性來寫。
- 懶加載是在get方法里對對象進行初始化,必須用點語法訪問屬性。
第8條:理解“對象等同性”
- ==比較的是兩個指針本身,并不是對象。NSObject用isEqual和hash方法判斷兩個對象是否相等。
- 相同的對象必須具有相同的hash碼,但hash碼相同的兩個對象未必相同。
- hash是對象等同性的必要非充分條件,在NSSet和NSDictionary中判斷時,會先判斷hash值是否相等,如果相等,那么就會進行isEqual的判斷;反之,不相等,直接判斷對象不相等
第9條:以“類族模式”隱藏實現細節
- 類族模式可以把實現細節隱藏在一套公共接口后面