39

Objective-C で @protected プロパティを宣言して、階層内のサブクラスのみがアクセスできるようにする回避策を見つけようとしています (読み取り専用で、書き込みはできません)。これを行う方法が文書化されていないことを読んだので、この回避策を考え、それについて StackOverflow の意見を聞きたいと思いました。

階層の最上位にあるすべてのカスタム クラスには、1 つの実装と 2 つのインターフェイスの 3 つのクラスが含まれます。それらに名前を付けましょう:

ClassA.h
ClassA_protected.h
ClassA.m

次に、この ClassA のサブクラスは通常どおりになります。

ClassB.h
ClassB.m

最初に、保護された int 変数を宣言するインターフェイスClassA.hを作成して、ClassA のすべてのサブクラスがそれにアクセスできるようにします。

@interface ClassA : NSObject{
    @protected
    int _myProtectedInt;
}
@end

次のステップは、私が話していた回避策です。しかし、一度読んでみると、それが非常に単純であることがわかります。ClassA_protected.hという 2 番目のインターフェイスを宣言しました。これは実際には ClassA.h の拡張機能として機能し、プロパティに次のタグを付けることができますreadonly

#import "ClassA.h"
@interface ClassA ()
@property (nonatomic , readonly) int myProtectedInt;
@end

保護された階層を準備する最後のステップは、プロパティのみを合成するClassA.mでその実装を宣言することです。

#import "ClassA_protected.h"
@implementation ClassA
@synthesize myProtectedInt = _ myProtectedInt;
@end

このように、 ClassA.h のサブクラスである必要があるすべてのクラスは、代わりにClassA_protected.hをインポートします。したがって、ClassB.hなどの子は次のようになります。

#import "ClassA_protected.h"
@interface ClassB : ClassA
@end

ClassB.mの実装からこのプロパティにアクセスする例:

@implementation ClassB
-(void) method {
    //edit protected variable 
    _myProtectedInt= 1;

    //normal access
    self.muProtectedInt;
}
@end
4

4 に答える 4

20

Sure, that works fine. Apple uses the same approach for example in the UIGestureRecognizer class. Subclasses have to import the additional UIGestureRecognizerSubclass.h file and override the methods that are declared in that file.

于 2012-06-15T09:05:59.317 に答える
6

単純な「プロパティ」の場合は、代わりに ivar を使用してください。これは、すべての実用的な目的のプロパティと同じくらい優れています。

さらに、デフォルトはすでに保護されています。

于 2013-06-10T08:00:26.493 に答える
3

If you ask for opinion, this is mine: If one decides to mutate your

_myProtectedInt

he will probably succed anyway, because it's definitely possible with Objective-C runtime. Except this, your solution is quite OK.

于 2012-06-15T09:06:18.163 に答える