Xét đoạn mã sau:Objective-C đối tượng typedef sản lượng @encode lạ và phá vỡ KVC
#import <Foundation/Foundation.h>
#import <objc/runtime.h>
typedef NSString* MyStringRef;
typedef NSString MyString;
@interface ClassA : NSObject
@property (nonatomic, copy) MyStringRef stringA;
@property (nonatomic, copy) MyString *stringB;
@end
@implementation ClassA
@synthesize stringA = _stringA;
@synthesize stringB = _stringB;
@end
int main() {
unsigned int count = 0;
Ivar *ivars = class_copyIvarList([ClassA class], &count);
for (unsigned int i = 0; i < count; i++) {
Ivar thisIvar = ivars[i];
NSLog(@"thisIvar = %s, %s", ivar_getName(thisIvar), ivar_getTypeEncoding(thisIvar));
}
ClassA *a = [[ClassA alloc] init];
NSLog(@"Out: %@", [a valueForKey:@"stringA"]);
NSLog(@"Out: %@", [a valueForKey:@"stringB"]);
}
Đây là kết quả:
$ clang --version
Apple clang version 3.1 (tags/Apple/clang-318.0.58) (based on LLVM 3.1svn)
Target: x86_64-apple-darwin11.4.0
Thread model: posix
$ clang -o typedef -fobjc-arc -framework Foundation typedef.m && ./typedef
2012-06-06 20:14:15.881 typedef[37282:707] thisIvar = _stringA, @"NSString"
2012-06-06 20:14:15.884 typedef[37282:707] thisIvar = _stringB, ^{NSString=#}
2012-06-06 20:14:15.885 typedef[37282:707] Out: (null)
2012-06-06 20:14:15.888 typedef[37282:707] *** Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[<ClassA 0x7fabe0501480> valueForUndefinedKey:]: this class is not key value coding-compliant for the key stringB.'
*** First throw call stack:
(
0 CoreFoundation 0x00007fff835fef56 __exceptionPreprocess + 198
1 libobjc.A.dylib 0x00007fff878e5d5e objc_exception_throw + 43
2 CoreFoundation 0x00007fff836891b9 -[NSException raise] + 9
3 Foundation 0x00007fff83e77703 -[NSObject(NSKeyValueCoding) valueForUndefinedKey:] + 240
4 Foundation 0x00007fff83dae38e _NSGetUsingKeyValueGetter + 108
5 Foundation 0x00007fff83dae315 -[NSObject(NSKeyValueCoding) valueForKey:] + 392
6 typedef 0x000000010e84bc6d main + 317
7 typedef 0x000000010e84b9c4 start + 52
)
Các câu hỏi tôi có ở đây là là những gì nó về Mục tiêu -C gây ra các typedef NSString MyString
để có hiệu quả tạo ra một cấu trúc có chứa một biến loại Class
và sau đó sử dụng mà tôi sử dụng MyString
. ví dụ. các cấu trúc trông như thế này (sau khi trao đổi this):
struct NSString {
Class a;
};
Nó loại có ý nghĩa nhưng làm cho valueForKey:
thất bại, có lẽ bởi vì nó là một cấu trúc hiện nay, vì vậy nó không thể trở về mà trong cùng một cách như các đối tượng . Hoặc chính xác hơn, nó rơi vào phần "ném ngoại lệ" của đơn đặt hàng tìm kiếm described in the docs.
Tôi chỉ muốn hiểu những gì về ngôn ngữ gây ra điều này xảy ra và tại sao nó không thể xử lý 2 typedef của tôi theo cùng một cách.
Mặc dù bạn tổng hợp các thuộc tính, bạn dường như không có một thanh công cụ thực sự sao lưu chúng. –
Các phiên bản gần đây của trình biên dịch tạo ra các mã vạch cho các đặc tính tổng hợp tự động. –
Nói chung, chuỗi @encode không hữu ích lắm. Họ nhanh chóng trở nên quá phức tạp khi giao dịch với các loại C++, ví dụ. – bbum