《Effective Objective-C 2.0》讀書筆記(三)——消息、運行期

11.理解objc_msgSend作用

靜態綁定(static binding):在編譯期就能決定運行時所應調用的函數
動態綁定(dynamic binding):所調用的函數在運行期才能確定
void objc_msgSend(id self,SEL cmd,..)
  • self:代表接收者
  • SEL:代表@selector()
  • ...:代表消息后續參數
流程
  • 在接收者所屬的類中搜尋其“方法列表”,找到,則跳轉至實現代碼
  • 找不到,沿著繼承體系向上查找,找到,再跳轉
  • 還找不到,執行消息轉發(message forwarding)
其他函數
  • objc_msgSend_stret:發送的消息返回結構體
  • objc_msgSend_fpret:發送的消息返回浮點數
  • objc-msgSendSuper:如果要給超類發消息

12.理解消息轉發機制

消息轉發流程圖

13.用“方法調配技術”調試“黑盒方法”

  • 獲取方法實現:Method class_getInstanceMethod(Class cls, SEL name)

  • 交換方法實現:void method_exchangeImplementations(Method m1, Method m2)
    <pre><code>
    -(void)example13{

    NSString *testStr = @"tesT the StRing";

    NSString *lowercaseString = [testStr lowercaseString];

    pr_obj(lowercaseString);

    NSString *uppercaseString = [testStr uppercaseString];

    pr_obj(uppercaseString);

    Method originalMethod = class_getInstanceMethod([NSString class],
    @selector(lowercaseString));

    Method swappedMethod = class_getInstanceMethod([NSString class],
    @selector(uppercaseString));

    method_exchangeImplementations(originalMethod, swappedMethod);

    lowercaseString = [testStr lowercaseString];

    pr_obj(lowercaseString);

    uppercaseString = [testStr uppercaseString];

    pr_obj(uppercaseString);
    }
    </pre></code>

結果

14.理解“類對象”的用意

  • id:通用對象類型

如果聲明時指定具體類型,在該類實例中調用該類沒有的方法時,編譯器會警告,而id不會

  • isMemberOfClass:判斷對象是否為某個類的實例,不包括父類和子類
  • isKindOfClass:判斷對象是否為某個類的實例或其派生類的實例,包括父類,不包括子類

<pre><code>

pragma mark - Grandpa

@interface Grandpa : NSObject

@end

@implementation Grandpa

@end

pragma mark - Father

@interface Father : Grandpa

@end

@implementation Father

@end

pragma mark - Son

@interface Son : Father

@end

@implementation Son

@end
</pre></code>

<pre><code>
-(void)example14{

Father *father = [[Father alloc] init];

pr_int([father isMemberOfClass:[Grandpa class]]);
pr_int([father isMemberOfClass:[Father class]]);
pr_int([father isMemberOfClass:[Son class]]);


pr_int([father isKindOfClass:[Grandpa class]]);
pr_int([father isKindOfClass:[Father class]]);
pr_int([father isKindOfClass:[Son class]]);

}
</pre></code>

結果
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容