1. 程式人生 > >剖析執行時(讓你看懂執行時)

剖析執行時(讓你看懂執行時)

init ont get tle pre art details ddc down

  • 執行時機制:比較高級的特性,純C語言
  • 實際上我們平時寫的OC代碼。都是轉成C語言的執行時代碼,執行時代碼的效率更高,更直接

Person.h

@interface Person : NSObject
@property(nonatomic,assign)int age;
@end

main.m

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        Person *p = [[Person alloc]init];

        p.age = 10;
    }
    return
0; }

我們來窺探底層對我們的這兩句代碼做了什麽事情:

int main(int argc, const char * argv[]) {
    /* @autoreleasepool */ { __AtAutoreleasePool __autoreleasepool; 
        Person *p = ((Person *(*)(id, SEL))(void *)objc_msgSend)((id)((Person *(*)(id, SEL))(void *)objc_msgSend)((id)objc_getClass("Person"), sel_registerName("alloc"
)), sel_registerName("init")); ((void (*)(id, SEL, int))(void *)objc_msgSend)((id)p, sel_registerName("setAge:"), 10); } return 0; }
  • 可能這樣看起來有點亂,我略微整理一下:
    alloc,init底層就是這種:
id pp = objc_msgSend(objc_getClass("Person"), sel_registerName("alloc"));

        Person *p = objc_msgSend(pp, sel_registerName("init"
));

事實上就是給Person這個類發送一個alloc消息,然後返回一個Person對象,再給Person這個對象,發送一個init消息。返回一個初始化完成的對象。


我們繼續看:

objc_msgSend(p, sel_registerName("setAge:"), 10);

這裏是給Person對象發送一個setAge:消息,參數是10.


那麽我們在main中的代碼,我們事實上也能夠這麽寫:

#import "Person.h"
#import <objc/message.h>
int main(int argc, const char * argv[]) {
    @autoreleasepool {
        Person *p = [[Person alloc]init];

        objc_msgSend(p, @selector(setAge:),20);

        NSLog(@"%d",p.age);

//        p.age = 10;

    }
    return 0;
}

然而,這個可能你們還不能看出執行時有什麽優點。詳細的執行時的優點,看我之前寫的博客:給執行時加入屬性
執行時的常見三種使用方法

剖析執行時(讓你看懂執行時)