#PRagma mark -- 1.了解OC的起源 /* 不說了。。。。 */#pragma mark -- 2.在類的頭文件中盡量少引用其他類的頭文件 /* 1.在編譯一個類文件時,不需要知道類的全部細節,編譯時,會引入很多用不到的細節,增加編譯時間 2.除非有必要,請在.m文件中引入其他類的頭文件,可以降低類之間的耦合 */#pragma mark -- 3.多用字面量語法,少用與其等價的方法//-(void)three{// NSString *num = @"3";// NSArray *array = @[@"3"];// NSDictionary *dic = @{};//} /* 1. 字面量語法的局限性,除了字符串以外,所創建出來的對象必須屬于Foundation框架 */#pragma mark -- 4.多用類型常量,少用#define預處理指令 /* 1.通過宏定義出來的常量沒有類型信息 2.通過定義常量替代宏定義, static const int a = 1; 3.通過此方式定義的常量包含類型信息,清楚地描述了常量的含義。 4.全局常量 --.h文件 extern NSString *const name; --.m文件 NSString *const name = @""; 5.在頭文件中使用extern來聲明全局常量 */#pragma mark -- 5.用枚舉表示狀態,選項,狀態碼 /* 1.枚舉是一種常量的命名方式,每種狀態都用一個便于理解的值表示,使代碼更易懂。 -- enum state { play, stop }; typedef enum state b; -(void)state{ b a = play; } 2.C++11標準修訂了枚舉的某些特性,可以指明用何種“底層數據類型”來保存枚舉類型的變量。 -- enum state : NSInteger { play, stop }; 3.Foundation定義了一些輔助宏,也可以定義枚舉 --普通枚舉類型 typedef NS_ENUM(NSUInteger, a) { b, c }; --選項枚舉類型 typedef NS_OPTIONS(NSUInteger, cc) { enumone = 1 << 0, enumtwo = 1 << 1 }; 4.要點: --1.處理枚舉switch語句時,不要實現default分支。這樣,加入新枚舉時,編譯器會提示switch中有新枚舉沒有處理 --2.NS_ENUM,NS_OPTIONS定義枚舉,并指明其底層數據類型,可以確保枚舉是開發者所選的底層數據類型實現出來的,而不會采用編譯器所選的類型。 */#pragma mark -- 6.屬性//@dynamic 編譯器不會自動為屬性生成get,set方法 /* 屬性 --原子性 ----nonatomic:不使用同步鎖 ----atomic:編譯器會通過其鎖定機制確保原子性 ----備注:atomic性能開銷較大。一個線程連續多次讀取某個屬性的同時,有別的線程同時改寫該值,即使是atomic也會讀到不同的值,如果為了線程安全,需要更深層的鎖定機制。所以iOS開發中大部分屬性都是nonatomic。 --讀寫權限 ----readwrite:可讀可寫,擁有get,set方法 ----readonly:可讀不能寫,擁有get方法,不創建set方法 --內存管理 ----assign:只針對純量類型的簡單賦值操作 ----strong:擁有關系,先保留新值,在釋放舊值,然后將新值設置上去 ----week:非擁有關系,不保留新值,也不釋放舊值,當屬性所指的對象被摧毀,屬性值被清空 ----unsafe_unretained:特質和assign相同,當屬性所指的對象被摧毀,屬性值不會被清空,不安全 ----copy:與strong類似,不保留新值,將其拷貝,保護其封裝性,屬性所指的對象是可變的,就應該用copy --方法名 @property (nonatomic, assign, getter = ison, setter = onononon:) BOOL on; -get方法變為 -(BOOL)isOn{ } -set方法變為 -(void)onononon:(BOOL)on{ } 重新設置get,set方法名 ----getter = <name>: ----setter = <name>:不常見 */#pragma mark -- 7.在對象內部盡量直接訪問實例變量 /* 直接訪問和通過屬性訪問的4點區別 1.直接訪問,不經過“方法派發”,直接訪問實例變量速度比較快,編譯器所生成的代碼會直接訪問儲存對象實例變量的那塊內存。 2.直接訪問實例變量,不會調用“設置方法”,繞過了為屬性設置的“內存管理語義”,比如,ARC下直接訪問一個聲明為copy的屬性,并不會拷貝該屬性,只會保留新值并釋放舊值。 3.直接訪問實例變量不會觸發鍵值觀測(KVO) 4.通過屬性訪問有助于排查問題,“獲取方法”,“設置方法”,監控該屬性的調用者以及訪問時機 ---------------------- 寫入實例變量的時候通過其“設置方法”,獲取實例變量的時候直接訪問 理由:提高讀取速度,又能控制屬性的寫入操作,能夠確保相關屬性的“內存管理語義”得以貫徹。 注意:1.初始化時,如果屬性在父類中定義,子類中無法直接訪問,只能通過屬性方法訪問。其他情況建議直接訪問。 2.用“懶加載”時,必須用“獲取方法”讀取實例變量。如果直接訪問,將會看到沒有設置好的屬性。 */#pragma mark -- 8.理解“對象等同性” /* 1、比較兩個對象,“==”比較的是兩個指針,而不是其所指的對象。 應該用“isEqual”判斷兩個對象的等同性, 2、NSObject類中有兩個比較等同性方法 -----若兩個對象相等,則其hash碼一定相等。 -----若兩個hash碼相等,其對應的對象不一定相等 - (BOOL)isEqual:(id)object; + (NSUInteger)hash; 3、----- - (BOOL)isEqual:(id)object; 的實現機制 --1.首先判斷兩個指針是否相等,若相等則受測對象必定相等 --2.判斷兩個對象的類,如果類不相同,則兩個對象必定不相等。(在繼承體系中,父類可能等于子類) --3.最后檢查每個屬性是否相等,都相等,則兩個對象相等。 4、深度等同性判定:比較兩個數組,先比較數組個數,然后每個元素比較“isEqual”,若都相等,則兩個數組相等 5、容器中可變類的等同性: -將兩個相同的可變數組(NSMutableArray *A, NSMutableArray *B)放入set中,最后set只保留NSMutableArray *A,(因為兩個數組相同)。 -將兩個不同的數組(NSMutableArray *A, NSMutableArray *B)放入set中,set中有兩個數組,然后改變NSMutableArray *B與NSMutableArray *A相等。此時set中會有兩個相同的對象。會有隱患。 */
新聞熱點
疑難解答