26

スーパークラスでMyClass

@interface MyClass : NSObject

@property (nonatomic, strong, readonly) NSString *pString;

@end

@implementation MyClass

@synthesize pString = _pString;

@end

サブクラスでMySubclass

@interface MySubclass : MyClass

@end

@implementation MySubclass

- (id)init {
    if (self = [super init]) {
        _pString = @"Some string";
    }
    return self;
}

問題は、コンパイラがそれ_pStringがのメンバーであるとは見なさないことですが、MySubclassでアクセスするのに問題はありませんMyClass

私は何が欠けていますか?

4

3 に答える 3

54

_pStringによって生成されるインスタンス変数@synthesizeは、にプライベートですMyClass。アクセスできるようにするには、保護する必要があります。MySubclass

次のよう_pStringに、の@protectedセクションにivar宣言を追加します。MyClass

@interface MyClass : NSObject {
    @protected
    NSString *_pString;
}

@property (nonatomic, strong, readonly) NSString *pString;

@end

ここで、通常どおりアクセサーを合成すると、変数がサブクラスにアクセスできるようになります。

于 2012-06-08T04:35:09.523 に答える
5

私はこの問題に精通しています。.mクラスで変数を合成します。これは、_pString変数がインターフェイスではなく実装の一部として作成されるため、ヘッダーと一緒にインポートされないためです。解決策は、ヘッダーインターフェイスで_pStringを宣言し、それをとにかく合成することです(プライベート変数を作成する代わりに、既存の変数を使用します)。

@interface MyClass : NSObject
{
    NSString *_pString; //Don't worry, it will not be public
}

@property (nonatomic, strong, readonly) NSString *pString;

@end
于 2012-06-08T04:30:08.980 に答える
0

与えられた答えは完全にうまく機能します。これは別の答えであり、どうやらAppleはもう少し好きだそうです

クラスのプライベート拡張子であるファイルを定義できます。MyClass+Protected.hファイルはとに含める必要がありMyClass.mますMySubclass.m

次に、この新しいファイルで、プロパティをとして再定義しますreadwrite

@interface MyClass ()
@property (strong, readwrite) NSString * pString;
@end

self.pStringこの代替手段により、ivarではなくアクセサーを使用できます_pString

注:の定義をそのままにしておく必要がありpStringますMyClass.h

于 2017-01-17T15:39:10.170 に答える