所以,我一直在與objc運行時插科打諢再次(驚喜驚喜),我發現的代碼here一個有趣的塊:爲什麼我們不能使用C字符串作爲SEL?
const char *sel_getName(SEL sel) {
#if SUPPORT_IGNORED_SELECTOR_CONSTANT
if ((uintptr_t)sel == kIgnore) return "<ignored selector>";
#endif
return sel ? (const char *)sel : "<null selector>";
}
那麼,這是什麼告訴我的是,一個SEL
相當於以C字符串,在每個習慣做法。做前16個字節包含@selector(addObject:)
SEL中的十六進制轉儲給出以下:
61 64 64 4F 62 6A 65 63 74 3A 00 00 00 00 00 00
其等於C字符串addObject:
。
這樣說,爲什麼當我使用C字符串作爲選擇器時,此代碼崩潰?
SEL normalSEL = @selector(addObject:);
SEL cStringSEL = (SEL) "addObject:";
NSMutableArray *arr = [NSMutableArray arrayWithObjects:@"1", @"2", nil];
[arr performSelector:normalSEL withObject:@"3"];
[arr performSelector:cStringSEL withObject:@"4"];
NSLog(@"%@", arr);
據我所知道的,選擇的內容是相同的,那麼,爲什麼在第二個與以下錯誤消息的崩潰?
***
終止應用程序由於未捕獲的異常 'NSInvalidArgumentException', 原因: ' - [__ NSArrayM ADDOBJECT:]:無法識別的選擇發送到實例 0x101918720'***
請注意,您可以使用'sel_registerName()'將一個C字符串變成一個有福的SEL(它基本上不區分背後的字符串以保留後續的指針標識)。還要注意,你永遠不應該直接依賴一個作爲char *的SEL。它可能總是會的,但這並不能使這個假設正確。 – bbum