私は、Objective-Cで@protectedプロパティを宣言して、階層内のサブクラスのみがそれらにアクセスできるようにする(読み取り専用、書き込みではない)回避策を見つけようとしました。これを行うための文書化された方法がないことを読んだので、この回避策を考え、それについてStackOverflowの意見を聞きたかった。
階層の最上位にあるすべてのカスタムクラスには、3つのクラス、1つの実装、2つのインターフェイスが含まれています。それらに名前を付けましょう:
ClassA.h
ClassA_protected.h
ClassA.m
次に、このClassAのサブクラスは通常どおりになります。
ClassB.h
ClassB.m
まず、インターフェイスClassA.hを作成しました。ここで、保護されたint変数を宣言して、ClassAのすべてのサブクラスがアクセスできるようにします。
@interface ClassA : NSObject{
@protected
int _myProtectedInt;
}
@end
次のステップは、私が話していた回避策です。しかし、それを読むと、それは非常に簡単であることがわかります。 ClassA_protected.hと呼ばれる2番目のインターフェイスを宣言しました。これは実際にはClassA.hのextensionとして機能し、タグを付けることができます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
確かに、それはうまくいきます。 Appleは、たとえばUIGestureRecognizer
クラスで同じアプローチを使用します。サブクラスは、追加のUIGestureRecognizerSubclass.h
ファイルをインポートし、そのファイルで宣言されているメソッドをオーバーライドする必要があります。
単純な「プロパティ」の場合は、代わりにivarを使用してください。それはすべての実用的な目的のためのプロパティと同じくらい良いです。
さらに、デフォルトはすでに保護されています。
あなたが意見を求めるなら、これは私のものです:
_myProtectedInt
それはObjective-Cランタイムで確実に可能であるため、おそらく彼はとにかく成功するでしょう。これを除いて、あなたの解決策はまったく問題ありません。
実装でのみ保護ヘッダーをインポートします。例えば.
ClassB.h
#import "ClassA.h"
@interface ClassB : ClassA
@end
ClassB.m
#import "ClassA_protected.h"
@implementation ClassB
@end
また、フレームワークでは、保護されたヘッダーをプロジェクトとしてマークして、フレームワークのパブリックヘッダーに含まれないようにする必要があります。 Apple通常、保護されたメソッドにはサフィックス_Internal.hを使用します。
遅延読み込みされたgetプロパティを初期化またはオーバーライドするには、@ proteced ivarに直接アクセスする必要がありますが、使用する場合は、代わりにプロパティをreadwriteとして再宣言してから、セッターの機能(アトミック性など)を利用できます。 。