Vì vậy, tôi đã rối tung xung quanh với các objc-runtime nữa (ngạc nhiên ngạc nhiên), và tôi thấy một khối thú vị của mã here:Tại sao chúng ta không thể sử dụng C-strings như SELs?
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>";
}
Vì vậy, điều này nói với tôi là một SEL
tương đương vào một chuỗi C, theo mọi cách thức. Làm một bãi chứa hex của 16 byte đầu tiên của SEL có chứa @selector(addObject:)
đưa ra sau đây:
61 64 64 4F 62 6A 65 63 74 3A 00 00 00 00 00 00
Đó là bằng C-string addObject:
.
Với điều đó đã nói, tại sao mã này gặp sự cố khi tôi sử dụng chuỗi C làm công cụ chọn?
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);
Theo như tôi có thể biết, nội dung của bộ chọn giống nhau, vậy tại sao tai nạn trên hộp chọn thứ hai có thông báo lỗi sau?
***
Chấm dứt ứng dụng do ngoại lệ còn tự do 'NSInvalidArgumentException', lý do: '- [__ NSArrayM AddObject:]: chọn không được công nhận gửi đến dụ 0x101918720'***
Lưu ý rằng bạn có thể sử dụng 'sel_registerName()' để biến một chuỗi C thành một SEL may mắn (về cơ bản chỉ đơn giản là chuỗi đằng sau hậu trường để bảo tồn danh tính con trỏ tiếp theo). Cũng lưu ý rằng bạn không nên trực tiếp dựa vào SEL là 'char *'. Nó có lẽ sẽ luôn luôn, nhưng điều đó không làm cho giả định chính xác. – bbum