2009-10-16 3 views
6

У меня есть класс, который выглядит следующим образом:#typedef и КВЦ в ObjC

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

где NSNumberBool является ЬурейеЕ:

// in MyApp_Prefix.pch 
typedef NSNumber NSNumberBool; 

У меня есть все необходимые @property и @synthesize декларации в сделать свойства prop1 и prop2.

Все скомпилировано и работает нормально, пока я не попытался получить доступ к prop2 по [myProperties valueForKey: @ "prop2"]. Это дает мне ошибку «class is not key-value compliant». Тем не менее, многие подобные звонки работают нормально:

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

Что происходит здесь, и как я могу это исправить?

Спасибо,

+1

Действительно странно, сталкиваясь с тем же вопросом.Также, если вы выполняете '[myProperties отвечаетToSelector: @selector (prop2)]', он также возвращает YES – jjramos

ответ

1

Это довольно старый пост, но я пришел к нему, ища решение этой проблемы, которое прекрасно решается директивой Objective-C 2.0 @compatibility_alias. Это позволяет написать:

@compatibility_alias NSNumber NSNumberBool; 

и есть псевдоним, созданный для NSNumber. KVO отлично работает с ним.

В соответствии с принятым в настоящее время ответом это имеет большое значение для безопасности типов.

4

От компиляции примера и выдачи class-dump на него, он появляется ЬурейеЕ становится превращается в

struct NSNumber { 
    Class _field1; 
}; 

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

Изменение ЬурейеЕ на это, кажется, работает хорошо, хотя, возможно, не совсем то, вы хотите.

#define NSNumberBool NSNumber 
+0

Спасибо. Хорошее объяснение + достойное обходное решение – tba

4

Я подозреваю, что это проблема с тем, как typedef взаимодействует с методом кодирования.

Я считаю, что typedef остается чистым ключевым словом C и на самом деле происходит только с типами Objective-C «обычно», потому что они реализуются как структуры.

В результате, когда вы вводите NSNumber в NSNumberBool, он отлично подходит для вызовов методов (и синтаксических свойств точек), но (при условии, что моя теория верна), прерывает кодирование, которое не может сказать, что NSNumberBool и NSNumber являются одним и тем же типом.

Мне будет интересно узнать, что говорит кто-то, кто знает лучше.

1

Как и в ответе nall, я также попробовал класс-дамп. Я нашел интересное, если уродливое обходное решение. Следующий код:

typedef NSNumber* NSNumberBoolPtr; 

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

класса отвалов на:

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

@end 

Опять же, не совсем то, что вы хотите, но вы получите время компиляции проверки, не имея NSNumbers и NSNumberBools переплетение (который я предполагаю, причина типизации в первую очередь).

Смежные вопросы