2009-10-16 24 views
6

Tôi có một lớp trông như thế này:#typedef và KVC trong ObjC

@interface Properties : NSObject { 
@private 
    NSNumber* prop1; 
    NSNumberBool* prop2; 
    //etc 

nơi NSNumberBool là một typedef:

// in MyApp_Prefix.pch 
typedef NSNumber NSNumberBool; 

tôi có tất cả các @property và @synthesize tờ khai yêu cầu tạo các thuộc tính prop1 và prop2.

Mọi thứ được biên dịch và hoạt động tốt cho đến khi tôi cố truy cập prop2 bằng [myProperties valueForKey: @ "prop2"]. Điều này cho tôi một lỗi "class không phải là key-value compliant". Tuy nhiên, nhiều cuộc gọi tương tự hoạt động tốt:

myProperties.prop2; //works 
[myProperties prop2]; //works 
[myProperties valueForKey:@"prop1"]; //works 
[myProperties valueForKey:@"prop2"] // throws NSUnknownKeyException ?? 

Điều gì đang xảy ra ở đây và cách khắc phục?

Cảm ơn,

+1

Thật kỳ lạ, tự mình gặp phải vấn đề tương tự.Ngoài ra nếu bạn làm '[myProperties respondsToSelector: @selector (prop2)]' nó trả về YES cũng như – jjramos

Trả lời

1

Đây là một bài đăng cũ, nhưng tôi đã tìm ra giải pháp cho vấn đề này, được giải quyết một cách độc đáo theo chỉ thị của Mục tiêu-C 2.0 @compatibility_alias. Điều này cho phép bạn viết:

@compatibility_alias NSNumber NSNumberBool; 

và có bí danh được tạo cho NSNumber. KVO hoạt động hoàn hảo với nó.

Trong câu trả lời hiện được chấp nhận, điều này mang lại lợi ích to lớn cho việc an toàn kiểu.

4

Từ biên soạn dụ của bạn và phát hành class-dump vào nó, nó xuất hiện typedef là nhận được biến thành

struct NSNumber { 
    Class _field1; 
}; 

@interface Properties : NSObject 
{ 
    NSNumber *prop1; 
    struct NSNumber *prop2; 
} 

Thay đổi typedef để điều này dường như làm việc tốt, mặc dù có lẽ không chính xác những gì bạn muốn.

#define NSNumberBool NSNumber 
+0

Cảm ơn. Giải thích tốt + cách giải quyết tốt – tba

4

Tôi nghi ngờ đây là vấn đề với cách typedef tương tác với phương pháp mã hóa.

Tôi tin rằng typedef vẫn là một từ khóa C thuần túy và thực sự chỉ xảy ra để làm việc với các kiểu "Mục tiêu-C" thường là do chúng được triển khai dưới dạng cấu trúc. Kết quả là khi bạn gõ NSNumber vào NSNumberBool, nó hoạt động tốt cho các cuộc gọi phương thức (và thuộc tính cú pháp dấu chấm) nhưng (giả định lý thuyết của tôi là chính xác), ngắt mã hóa mà không thể nói rằng NSNumberBool và NSNumber là cùng loại.

Tôi sẽ quan tâm để xem người nào biết rõ hơn.

1

Tương tự như câu trả lời của nall, tôi cũng đã thử lớp kết xuất. Tôi đã tìm thấy một giải pháp thú vị, nếu xấu xí. Các mã sau đây:

typedef NSNumber* NSNumberBoolPtr; 

@interface Test : NSObject { 
    NSNumber *real; 
    NSNumberBoolPtr poser; 
} 

đẳng cấp bãi để:

@interface Test : NSObject 
{ 
    NSNumber *real; 
    NSNumber *poser; 
} 

@end 

Một lần nữa, không phải chính xác những gì bạn muốn nhưng bạn sẽ có được thời gian biên dịch kiểm tra không có NSNumbers và NSNumberBools xen (đó là tôi giả lý do cho typedef ở nơi đầu tiên).