子类化时访问属性

时间:2014-05-02 22:13:39

标签: objective-c inheritance initialization subclass

我最近意识到使用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;
}

这并不是:

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

        _whatever = 100;
    }
    return self;
}

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

根据要求,基类的标题:

#import <Foundation/Foundation.h>

@interface DTCharacter : NSObject

@property BOOL isIdle;

@end

我使用自动合成,因此在基类的实现中没有关于此变量的内容。

子类的头文件也没有提及或引用该变量。

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

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

    if (self) {
        [self createName];

        _isIdle = YES;  //says use of undeclared identifier
        //this would work: self.isIdle = YES;
    }
return self;
}

3 个答案:

答案 0 :(得分:5)

如果属性,访问initdealloc中的属性可能会有问题 访问器方法对对象的 state 进行假设,这可能不是 在部分构造的对象中实现。

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

self = [super init];

self的“超级部分”已完全构建,因此可以安全地调用

self.whatever = 100;

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

_whatever = 100;

在子类中不起作用,因为自动合成的实例变量 仅在超类本身中可见。您可以明确声明它来实现它 对子类可见,但没有必要这样做。

答案 1 :(得分:2)

Martin的回答是最好的,因为你真的不需要为超类属性做这个(并且可能不应该,基于类实现应该是私有的理论,甚至从子类到可能的程度)。但是,如果你想这样做,这里有一个例子来说明:

的main.m:

#import <Foundation/Foundation.h>
#import "PGRBase.h"

int main(int argc, const char * argv[])
{

    @autoreleasepool {
        PGRChild * theObject = [PGRChild new];
        NSLog(@"Property is %d\n", theObject.prop);

    }
    return 0;
}

PGRBase.h:

#import <Foundation/Foundation.h>

@interface PGRBase : NSObject {
    int _prop;
}

@property (readwrite, nonatomic, assign) int prop;

@end

@interface PGRChild : PGRBase

@end

PGRBase.m:

#import "PGRBase.h"

@implementation PGRBase

- (instancetype)init
{
    self = [super init];
    if ( self ) {
        _prop = 1;
    }
    return self;
}

@end

@implementation PGRChild

- (instancetype)init
{
    self = [super init];
    if ( self ) {
        _prop = 2;
    }
    return self;
}

@end

NSLog()通话记录Property is 2

答案 2 :(得分:0)

有一些代码片段可以让子类可以访问ivars:

@interface SomeBase : NSObject
{
@protected
    WhateverType* _whatever;
}
@end

因此_whatever的子类将显示SomeBase

相关问题