Почему подкласс @property без соответствующего ivar скрывает ivars суперкласса?

Следующее кажется достаточно простым. Есть суперкласс с ivar и подкласс, который обращается к ivar суперклассов (@protected):

// Testclass.h    
@interface TestClass : NSObject {
    NSString *testIvar;
}
@end

//TestClass.m
@implementation TestClass
@end

//TestSubclass.h
@interface TestSubClass : TestClass {
}

@property (nonatomic, retain) NSString *testProperty;
- (void) testMethod;

@end

//TestSubclass.m    
#import "TestSubClass.h"
@implementation TestSubClass

@synthesize testProperty;

- (void) testMethod{
    NSLog(@"The value was: %@", testIvar);
}
@end

Достаточно просто и правильно. Однако при попытке компиляции (для iOS 4.2 SDK с GCC 4.2) возникает эта ошибка, указывающая на строку NSLog: «testIvar undeclared».

Я новичок в Objective-C, но не могу понять, почему это должно быть ошибкой. Закомментируйте материал testProperty, и он скомпилируется. Кажется, что добавление синтезированного свойства в подкласс без соответствующего ivar на самом деле скрывает несвязанный ivar суперкласса.

Может ли кто-нибудь просветить меня относительно того, что здесь происходит? Соответственно, можно ли было предвидеть ошибку компиляции? (Предвидение этого сэкономило бы мне время и нервы).


person Cris    schedule 18.10.2010    source источник


Ответы (2)


LLVM компилирует исходники без нареканий, переключаемся на LLVM: Select target → Get Info → Build → C/C++ Compiler Version → LLVM 1.5. В любом случае, судя по моему ограниченному опыту, это лучший компилятор. Понятия не имею, почему GCC ведет себя именно так — интересная загвоздка.

person zoul    schedule 18.10.2010
comment
Спасибо. В любом случае, я собирался попробовать LLVM, так что вот случай. Я отметил ответ, поскольку вы предложили исправление, и, вероятно, только разработчики GNU и/или Apple будут знать истинную причину. - person Cris; 19.10.2010
comment
Я столкнулся с той же проблемой. Странный. LLVM ftw - person logancautrell; 25.02.2011
comment
Тоже столкнулся с той же проблемой. Никогда не использовал LLVM и обнаружил, что это лучше - person albianto; 11.08.2011

В этом случае необъявленная ошибка testIvar на самом деле является отвлекающим маневром. Это сообщение, по-видимому, вызвано тем, что testProperty не имеет соответствующего ivar. Чтобы решить эту проблему, либо объявите переменную testProperty в TestSubClass.h, либо сделайте testProperty @dynamic в TestSubClass.m.

person bspenla    schedule 01.07.2011