(Not So) Silly Objective-C inheritance problem when using property - GCC Bug?

后端 未结 4 1590
滥情空心
滥情空心 2020-12-05 15:40

Update - Many people are insisting I need to declare an iVar for the property. Some are saying not so, as I am using Modern Runtime (64 bit). I can confirm that I have bee

4条回答
  •  庸人自扰
    2020-12-05 16:15

    I think this is the bug of GCC 4.2.1. I made the file foo.m with the content

    #import 
    @interface TestA : NSObject {
        NSString *testString;
    }
    @end
    
    @implementation TestA  
    @end
    
    @interface TestB : TestA {
    }
    @property (retain) NSString *testProp;
    @end
    
    @implementation TestB
    @synthesize testProp;
    - (void)testing{
    NSLog(@"test ivar is %@", testString);
    }
    @end
    

    Note that it's OK in the 64 bit mode to omit the instance variable. My GCC 4.2.1 on OS X 10.6.3 gave me an error:

    $ gcc -arch x86_64 -c foo.m
    aho.m: In function ‘-[TestB testing]’:
    aho.m:19: error: ‘testString’ undeclared (first use in this function)
    aho.m:19: error: (Each undeclared identifier is reported only once
    aho.m:19: error: for each function it appears in.)
    

    This compiled without problem by changing

    NSLog(@"test ivar is %@", testString);
    

    to

    NSLog(@"test ivar is %@", self->testString);
    

    Clang compiled it without any problem.

    ( In the 32 bit mode, I got

    $ gcc -arch i386 -c foo.m
    aho.m:17: error: synthesized property ‘testProp’ must either be named 
    the same as a compatible ivar or must explicitly name an ivar
    aho.m: In function ‘-[TestB testing]’:
    aho.m:19: error: ‘testString’ undeclared (first use in this function)
    aho.m:19: error: (Each undeclared identifier is reported only once
    aho.m:19: error: for each function it appears in.)
    

    which is a perfectly expected behavior, as Manjunath wrote.)

    However I think it's generally a rather bad idea to access an instance variable of the superclass: when you implement the methods the superclass, you cannot assume anything about the instance variable because it might be tweaked in a worst manner possible by the subclass. You at least need to write down what kind of operation on the instance variable is permitted or not... Remember you might need to maintain your code for years! I would prefer keeping programming contracts between various parts of the code at the level of methods and properties.

    Finally you should change

    @property NSString *testProp;
    

    to

    @property (copy) NSString *testProp;
    

    or at least to

    @property (retain) NSString *testProp;
    

    if you're not using GC on OS X. Otherwise EXP_BAD_ACCESS will await you!

提交回复
热议问题