3

次のクラスとサブクラスがあります。

@interface NSHigh : NSObject
@property (nonatomic, strong) NSArray *array;
@end
@implementation NSHigh
-(NSArray*)array
{
    _array = [[NSArray alloc] init];
    return _array;
}
@end

@interface NSLow : NSHigh
@end
@implementation NSLow
/* synthesizing makes the assertion FAIL. NO synthesizing makes the assertion PASS */
@synthesize array;
@end

次に、このコードをどこかで実行します。

NSLow *low = [[NSLow alloc] init];
assert(low.array);

したがって、明らかに、サブクラスNSLowで配列プロパティを合成すると、スーパークラスからのゲッターは呼び出されず、アサーションは失敗します。

合成しないと、スーパークラスのゲッターが呼び出され、アサーションが渡されます。

  1. なぜこれが起こるのですか?
  2. 毎回NSLow呼び出すことなく、サブクラスの配列インスタンス変数にアクセスするにはどうすればよいですか?self.array
4

1 に答える 1

8

@synthesizeinNSLowは、次のゲッターを作成します。

- (NSArray *)array {
    return _array;
}

したがって、配列は初期化されずnilに返されます。

通常、スーパークラスで宣言されているものには使用@synthesizeしないでください。@properties

また、のようなゲッターを実装しないでくださいNSHigh。その配列を怠惰に初期化したい場合は、次のようにする必要があります。

- (NSArray *)array {
    if (!_array) {
        _array = [[NSArray alloc] init];
    }
    return _array;
}

NS最後に、プレフィックスは使用しないでください。

編集:

サブクラスのivarに直接アクセスする場合は、次のようにヘッダーで明示的に宣言できます。

@interface NSHigh : NSObject {
    NSArray *_array;
}
@property (nonatomic, strong) NSArray *array;
@end

これにより、サブクラスのivarにもアクセスできるようになります。

于 2012-10-03T00:02:08.587 に答える