6,理解 '屬性'這一概念
1, 可以用@property語法來定義對象中所封裝的數據。
2, 通過'特質'來定義指定存儲數據所需的正確語義
原子性,
讀寫權限, 可以在分類中重新定義
內存管理語義, 注意,NSString ?Block ?應為 Copy
方法名
3, 在設置屬性所對應的實例變量時,一定要遵從該屬性所聲明的定義
4, 開發iOS程序時,應該使用nonatomic屬性, 因為atomic屬性會嚴重影響性能。
如果使用
@dynamic 代替@synthesize
編譯器不會這個屬性自動創建存取方法,和合并存取方法,并不會自動創建實例變量。如果用代碼訪問其中的屬性,編譯器也不會發出警示信息
例如
@property (nonatomic,assign) intabc;
@dynamic abc;
這樣,如果用戶就不會創建 _abc 這個實例變量了
7,在對象內部盡量直接訪問實例變量
1, 在對象內部讀取數據時,應該直接通過實例變量,而寫入數據時,應該通過屬性
2, 在初始化和delloc方法中,總是應該通過實例變量來讀寫數據
3,有時會使用惰性初始化技術配置某份數據,這種情況下,需要同過屬性來讀取數據
8,理解‘對象等同性’這一概念
1,若想檢測對象的等同性,請提供 ‘isEqual’與hash 方法
2, 相同的對象必須有相同的哈希碼,但是兩個哈希碼相同的對象未必相同
3,不用盲目的逐個檢測每條屬性,而是應該依照具體需求來指定檢測方案
4, 編寫hash方法時,應該使用技術速度快而且哈希碼碰撞幾率低的算法
9,以’類族‘隱藏實現細節
1, 類族模式可以把實現細節隱藏在一套簡單的公共接口后面
2, 系統框架中經常使用類族
3,從類族的公共抽象類中集成子類時需要當心,如果有開發文檔,則應首先閱讀
---> 類族,就是常說的,抽象類的靜態方法、類方法來創建實例對象
10,在既有類中使用關聯對象存放自定義數據 ( 動態添加屬性,相當于給一個對象中粘貼了一個對象,并設置了相關的內存管理寓意 )
1, 可以使用關聯對象機制來把兩個對象連起來
2, 定義關聯對象可指定內存管理語義,用以模仿定義屬性時采用的 擁有關系 與 非擁有關系
3, 只有在其他方法不可行時,才贏選用關聯對象,因為這種做法通常會引入難以查找的BUG
-- > 相當于給一個物件 粘上一個物件, 內存管理,應該尊重內存管理語義
引用
#import"objc/runtime.h"
全局
staticvoid*SceneTest4Key =@"SceneTest4Key";
-(void)test6
{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Question"message:@"What do you want to do ?"delegate:self cancelButtonTitle:@"Cancel" otherButtonTitles:@"Continue",nil];
void(^block)(NSInteger) = ^(NSIntegerbuttonIndex){
if(buttonIndex == 0) {
[self doCancel];
}else{
[self doContinue];
}
};
objc_setAssociatedObject(alert,SceneTest4Key, block,OBJC_ASSOCIATION_COPY);
[alert show];
}
-(void)alertView:(UIAlertView*)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
void(^block)(NSInteger) =objc_getAssociatedObject(alertView,SceneTest4Key);
block(buttonIndex);
}
11,理解 objc_msgSend 的作用
1, 消息由接受者、選擇子和參數構成。給某對象'發送消息'也就是相當于在該對象上調用方法
2,發給某對象的全部消息都要由 ‘動態消息派發系統’來處理,該系統會查處對應的方法,并執行代碼
12,理解消息轉發機制
1, 若對象無法相應某個選擇子,則進入消息轉發流程
2,通過運行期的動態方法解析功能,我們可以在需要用到某個方法時再將其加入到類中
3,對象可以把某個無法解讀的選擇子轉交給其他對象處理
4,經過上述兩步后,若是還是沒辦法處理選擇子,那就啟動完整的消息轉發機制
調用方法的流程
1,首先檢測對象的類有沒有實現這個方法,有就調用,沒有繼續往下
2,向上檢測父類有沒有實現,直到根類?NSObject,如果都沒有實現就繼續往下
3,進入轉發機制,以此往下
方案一:拯救1,檢測動態添加
1
+?(BOOL)resolveInstanceMethod:(SEL)sel
1
+?(BOOL)resolveClassMethod:(SEL)sel
方案二:拯救2,檢測消息是否轉發
1
-?(id)forwardingTargetForSelector:(SEL)aSelector
方案三:拯救3,檢測用戶是否已經注冊過,可以注冊但不實現
1
-?(NSMethodSignature?*)methodSignatureForSelector:(SEL)aSelector;
1
-?(void)forwardInvocation:(NSInvocation?*)anInvocation;
13,用‘方法調配技術’調試‘黑盒方法’
1, 在運行時,可以向類中新增和替換選擇子所對應的方法實現
2,使用另一份實現來替換原有的方法實現,這道工序叫做,‘方法調配’,開發者常用此技術向原有實現中添加功能
3,一般來說,只有調試程序的時候,才需要在運行時修改方法實現,這種做法不易濫用
動態的交換方法
示例:AFN 使用了動態交換方法,交換了網絡獲取的方法,在網絡獲取的時候來發送通知
NSString*abc =@"NSString";
NSLog(@"大寫%@", [abcuppercaseString]);
NSLog(@"小寫%@", [abclowercaseString]);
MethodoriginalMethod =class_getInstanceMethod([NSStringclass],@selector(lowercaseString));
MethodswappedMethod =class_getInstanceMethod([NSStringclass],@selector(uppercaseString));
method_exchangeImplementations(originalMethod, swappedMethod);
NSLog(@"大寫%@", [abcuppercaseString]);
NSLog(@"小寫%@", [abclowercaseString]);
2016-05-01 12:10:54.239 EasyIOSDemo[3214:283447]大寫NSSTRING
2016-05-01 12:10:54.240 EasyIOSDemo[3214:283447]小寫nsstring
2016-05-01 12:10:54.241 EasyIOSDemo[3214:283447]大寫nsstring
2016-05-01 12:10:54.241 EasyIOSDemo[3214:283447]小寫NSSTRING
14,理解‘類對象’的用意
1, 每一個實例都有一個指向Class 對象的指針,用以表明其類型,而這些Class對象 則構成了類的繼承體系。 這個指針是 isa,對象指向類,類指向父類,直至NSObject
和swift 存在差別,swift中的 isa 始終指向所屬的類
2,如果對象類型無法在編譯期確定,那么就應該使用類型信息查詢方法類探知
3,盡量使用類型信息查詢方法類確定對象類型,而不要使用直接比較類對象,因為某些對象可能實現了消息轉發功能
NSMutableDictionary*dic = [NSMutableDictionarynew];
[dic isMemberOfClass:[NSDictionaryclass]];// NO
[dicisMemberOfClass:[NSMutableDictionaryclass]];// YES
[dic isKindOfClass:[NSDictionaryclass]];// YES
[dic isKindOfClass:[NSArrayclass]];// NO;
isMemberOfClass ?判斷對象是否是某個類的實例
isKindOfClass 盤對想想是否是某個類活其派生類的實例
----- > 類對象,[NSArrayclass]
NSMutableDictionary*dic = [NSMutableDictionarynew];
NSLog(@"%@, %@", [dicclass], [NSMutableDictionaryclass]);
NSDictionary*dic1 = [NSDictionarynew];
NSLog(@"%@, %@", [dic1class], [NSDictionaryclass]);
__NSDictionaryM, NSMutableDictionary
__NSDictionary0, NSDictionary
在AppDelegate中打印
NSLog(@"%@, %@", [super class], self.superclass);
顯示 [2146:51427] AppDelegate, UIResponder