剛開始接觸OC的時候就看過這本書,到現在應該已經看過三四次了,覺得這是一本很不錯的關于OC基礎的書(雖然是有些老),因為好久沒用過OC了(有快兩年了一直用Swift)有些OC的基礎東西已經有些生疏了,最近又重新找出來讀了一遍,順便記錄下重點,方便以后再次閱覽?
第四章
1.動態類型和動態綁定
OC是動態類型
OC 中的消息是在運行時采取綁定的。運行時系統首先會確定接受者的類型(動態類型識別),然后根據消息名在類的方法列表里選擇想要的方法執行,如 果沒找到就到父類中繼續尋找,假如一直到NSObject也沒有找到,則報告找不到方法的錯誤。
動態綁定(dynamic binding)指的就是程序執行是才確定對象的屬性和需要響應的消息。
Swift語言本事是靜態類型語言,但是與Cocoa一起使用時,可以通過訪問OC的運行時庫,來實現一些動態類的特性(method swizzling)
- 多態
- 同一操作作用于不同的類的實例時,將產生不同的執行結果,即同樣一個方法,不同的類對象調用時,產生不同的結果
可以通過類繼承,子類重寫方法,及OC似的通過id去掉用同一個方法,來實現多態
多態可以是程序更加的靈活可伸縮,但是因為沒有編譯器的檢查,也更加容易出錯
swift,C++,Java等強類型的語言實現多態,是基于類的層次結構,可以通過子類重寫父類中的方法來實現多態。而無法向OC一樣實現沒有類繼承關系的多態,OC也可以實現類繼承類型的多態
重載 一個函數、運算符、方法定義多重功能,比如C++中,同樣的方法明,可以根據參數的個數及類型的不同來決定執行不同的函數,OC是動態語言,參數的類型運行時才確定,所以不支持來根據參數來實現調用不同方法的重載,但是可以通過動態綁定,讓同一個消息選擇器執行不同的功能,來實現重載
2.類對象
- 類是一種定義對象的類型,但類本身也是一個對象,只不過類對象的生成是程序自動生成的,不需要手動創建,且只有一個
第五章 基于引用計數的內存管理
1.通過函數的參數返回結果對象 —103頁
寫回傳:通過函數或方法的參數傳入一個指針,將返回結果寫入指針指向的空間,實現一個方法多個返回值,OC中常用當一個方法處理過程中出現錯誤時,通過指向NSError的二重指針返回錯誤。
(instancetype)initWithContentsOfURL:(NSURL *)url ofType:(NSString *)typeName error:(NSError * _Nullable *)outError;
ARC情況下編譯器會自動為函數的二重指針添加 _ autoreleasing修飾符,在ARC下上面的方法被編譯為(只有在需要寫回傳的時候,才用 _autoreleasing修飾)
- (instancetype)initWithContentsOfURL:(NSURL *)url ofType:(NSString *)typeName error:(_ _autoreleasing NSError * _Nullable *)outError;
_ _autoreleasing的根本目的是獲得一個延遲釋放的對象,假設你想傳遞一個未初始化的對象的引用(二重指針形式)到一個方法中,并在此方法中實例化此對象,且希望方法返回時這個對象被加入到自動釋放池中,那么就用這個關鍵字。
NSError * error = nil;
NSString * string =[ [NSString alloc]initWithContentsOfURL“/path/file.text” encoding:utf8 error: &error];
編譯器將上面的代碼轉換為
NSError _ _strong * error = nil;
NSError _ _autoreleasing * tempError = error;
NSString * string =[ [NSString alloc]initWithContentsOfURL”/path/file.text” encoding:utf8 error: &tempError];
error = tempError;
error 被加入到自動釋放池中,一直保持到自動釋放池釋放為止
https://stackoverflow.com/questions/13587742/nserror-and-autoreleasing/13590696
第七章 屬性聲明
1.屬性的規則
自動生成訪問方法,可以通過修飾符進行限制
自動生成實例變量,如果不存在同名的實例變量的話,在生成訪問方法的同時,也會自動生成同名的實例變量
點語法進行訪問
屬性的內?。╥ntrospection)/反射:通過程序動態的訪問一個類所包含的方法和屬性的相關原信息的功能叫做內省或者方式,OC可以通過運行時去實現
2.@dynamic @synthesize
@synthesize 加上屬性名 寫在@implementation 和 @end 之間,@synthesize可以自定義對應屬性生成的實例變量的名字,也可以不使用@synthesize自動生成,我們也可以通過@dynamic關鍵字告訴編譯器不需要自動生成訪問方法,用戶可能在后期通過運行時等方法提供
@property聲明的屬性名稱和實例變量的名稱通常相同,如果你需要二者名字不同,可以為實例變量定義其他名字 @synthesize proName = otherName
3.屬性的修飾
修飾屬性的選項:assign, unsafe_unretauned, retain, strong, weak, copy, nonatomic
原子性 如果不設置nonatomic 則訪問方法是原子的,意味著在多線程環境下訪問屬性是安全的,在執行過程中不可被打斷,而nonatomic剛好相反,缺省情況下為原子的。在沒有指定nonatomic時getter方法和setter方法需要通過lock和unlock來保證原子性,實現如下: 訪問及賦值前先加鎖,完成后解鎖,135頁, atomic修飾的對象會保證 setter 和 getter 的完整性,任何線程對其訪問都可以得到一個完整的初始化后的對象。因為要保證操作完成,所以速度慢。它比 nonatomic 安全,但也并不是絕對的線程安全,例如多個線程同時調用 set 和 get 就會導致獲得的對象值不一樣。絕對的線程安全就要用 @synchronized。
屬性名字不能和方法族中的名字沖突,比如不能將屬性命名為new
You own any object you create
You create an object using a method whose name begins with “alloc”, “new”, “copy”, or “mutableCopy” (for example, alloc, newObject, or mutableCopy).
第八章 NSObject和運行時系統
1.類和實例
- isa :NSObject只有一個實例變量,就是Class類型的變量isa,isa用于表示實例對象屬于哪個類對象,決定了實例變量和類的關系
- 第十章 類別
1.類別和屬性的聲明
- 類別中可以包括屬性聲明,但是實現部分不能用@synthesize,實現部分需要手動的定義訪問方法,這是為了防止隨意訪問同一個類的不同文件中定義的實例變量??梢酝ㄟ^運行時方法提供對應的getter和setter方法的實現
-類別中可以覆蓋類原有的方法,但是不建議這樣做,容易出現問題
2.關聯引用
- 類別中不能添加實例變量,但是可以通過runtime,給已經存在的實例對象增加實例變量,這個功能叫關聯引用。這個功能和類別結合使用,不創建子類也能對類進行動態擴展 215頁