子类化时访问属性

baz*_*ola 2 inheritance initialization subclass objective-c

我最近意识到使用self.whatever = thing从init内部访问类的属性不是正确的形式,而是应该使用_whatever = thing直接访问属性.当我为基类设置值时,这很好用.但是,当我尝试在子类的init内设置值时,我收到错误"使用未声明的标识符_whatever".使用self.w从子类的init内部工作正常.

为了清楚起见,对于@property int在基础对象的接口中声明的任何内容,这将编译:

-(id) init {
    self = [super init];
    if (self) {
        [self createName];

        self.whatever = 100;
    }
    return self;
}
Run Code Online (Sandbox Code Playgroud)

而这不是:

-(id) init {
    self = [super init];
    if (self) {
        [self createName];

        _whatever = 100;
    }
    return self;
}
Run Code Online (Sandbox Code Playgroud)

我想我在这里误解了一些东西.我试着搜索我做错了什么,但我不知道要搜索的正确单词.

根据要求,基类的标头:

#import <Foundation/Foundation.h>

@interface DTCharacter : NSObject

@property BOOL isIdle;

@end
Run Code Online (Sandbox Code Playgroud)

我正在使用自动合成,因此在基类的实现中没有任何关于此变量的信息.

此外,子类的头文件未提及或引用该变量.

我正在尝试在子类的实现中分配它:

-(id) init {
    self = [super init];

    if (self) {
        [self createName];

        _isIdle = YES;  //says use of undeclared identifier
        //this would work: self.isIdle = YES;
    }
return self;
}
Run Code Online (Sandbox Code Playgroud)

Mar*_*n R 5

如果属性访问器方法对对象的状态进行假设(在部分构造的对象中可能无法实现),则访问属性initdealloc可能存在问题.

但这仅适用于类本身的属性,而不适用于超类的属性.后

self = [super init];
Run Code Online (Sandbox Code Playgroud)

"超级部分" self是完全构造的,因此可以安全地打电话

self.whatever = 100;
Run Code Online (Sandbox Code Playgroud)

在子类init方法中,设置在超类中声明的属性.

_whatever = 100;
Run Code Online (Sandbox Code Playgroud)

在子类中不起作用,因为自动合成的实例变量仅在超类本身中可见.您可以显式声明它以使其对子类可见,但不需要这样做.

  • 有苹果recomendation:不要使用在初始化方法和dealloc的存取方法(https://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/MemoryMgmt/Articles/mmPractical.html#//apple_ref/DOC/UID/TP40004447-SW6) (2认同)
  • 理想情况下,它是'self = [super initWithWhatever:100];`不再需要它. (2认同)