回答:
メソッドを保護またはプライベートとして宣言することはできません。Objective-Cの動的な性質により、メソッドのアクセス制御を実装することは不可能です。(コンパイラーまたはランタイムを大幅に変更することで、速度が大幅に低下する可能性がありますが、明らかな理由により、これは行われません。)
次のようにして、メソッドへの保護されたアクセスとプライベートアクセスをシミュレートできます。
Sachinが述べたように、これらの保護は実行時に適用されません(たとえば、Javaの場合)。
UIGestureRecognizerSubclass.h
メソッド自体を実装することを要求せずに、保護されたメソッドをサブクラスから見えるようにするために私がやったことは次のとおりです。これは、実装が不完全であることについて、サブクラスでコンパイラの警告を受け取らなかったことを意味します。
SuperClassProtectedMethods.h(プロトコルファイル):
@protocol SuperClassProtectedMethods <NSObject>
- (void) protectMethod:(NSObject *)foo;
@end
@interface SuperClass (ProtectedMethods) < SuperClassProtectedMethods >
@end
SuperClass.m:(コンパイラーは保護されたメソッドを追加するように強制します)
#import "SuperClassProtectedMethods.h"
@implementation SuperClass
- (void) protectedMethod:(NSObject *)foo {}
@end
SubClass.m:
#import "SuperClassProtectedMethods.h"
// Subclass can now call the protected methods, but no external classes importing .h files will be able to see the protected methods.
performSelector
それをすることができます。
[(id)obj hiddenMethod]
。正確に言うと、Objective-Cでは保護されたメソッドはサポートされていません。
Adamの答えを改善するために、スーパークラスで.mファイルに保護されたメソッドの実装を作成しますが、.hファイルでは宣言しないでください。サブクラスで、スーパークラスの保護されたメソッドの宣言を使用して.mファイルに新しいカテゴリを作成します。サブクラスでスーパークラスの保護されたメソッドを使用できます。これは、実行時に強制された場合、最終的に保護されていると思われるメソッドの呼び出し元を妨げません。
/////// SuperClass.h
@interface SuperClass
@end
/////// SuperClass.m
@implementation SuperClass
- (void) protectedMethod
{}
@end
/////// SubClass.h
@interface SubClass : SuperClass
@end
/////// SubClass.m
@interface SubClass (Protected)
- (void) protectedMethod ;
@end
@implementation SubClass
- (void) callerOfProtectedMethod
{
[self protectedMethod] ; // this will not generate warning
}
@end
protectedMethod
@protected変数を使用する別の方法。
@interface SuperClass:NSObject{
@protected
SEL protectedMehodSelector;
}
- (void) hackIt;
@end
@implementation SuperClass
-(id)init{
self = [super init];
if(self) {
protectedMethodSelector = @selector(baseHandling);
}
return self;
}
- (void) baseHandling {
// execute your code here
}
-(void) hackIt {
[self performSelector: protectedMethodSelector];
}
@end
@interface SubClass:SuperClass
@end
@implementation SubClass
-(id)init{
self = [super init];
if(self) {
protectedMethodSelector = @selector(customHandling);
}
return self;
}
- (void) customHandling {
// execute your custom code here
}
@end
カテゴリを使用してこれを並べ替えることができます。
@interface SomeClass (Protected)
-(void)doMadProtectedThings;
@end
@implementation SomeClass (Protected)
- (void)doMadProtectedThings{
NSLog(@"As long as the .h isn't imported into a class of completely different family, these methods will never be seen. You have to import this header into the subclasses of the super instance though.");
}
@end
別のクラスにカテゴリをインポートする場合、メソッドは非表示になりませんが、非表示にすることはありません。Objective-Cの動的な性質により、呼び出し元のインスタンスタイプに関係なく、メソッドを完全に非表示にすることは実際には不可能です。
最善の方法は、おそらく@Brian Westphalが回答したクラス継続カテゴリですが、サブクラス化されたインスタンスごとに、このカテゴリのメソッドを再定義する必要があります。
1つのオプションは、クラス拡張を使用することですしてメソッドを非表示にすることです。
で.h
:
@interface SomeAppDelegate : UIResponder <UIApplicationDelegate>
@property (strong, nonatomic) UIWindow *window;
@end
で.m
:
@interface SomeAppDelegate()
- (void)localMethod;
@end
@implementation SomeAppDelegate
- (void)localMethod
{
}
@end
@interface
.mファイルの宣言も必要ないと思います。関数を宣言して使用すれば、プライベートとして扱われます。