Objective-C中的受保护方法

时间:2010-09-16 10:43:42

标签: objective-c

Objective-C中受保护方法的等价物是什么? 我想定义只有派生类可以调用/实现的方法。

9 个答案:

答案 0 :(得分:153)

您可以通过执行以下操作模拟对方法的受保护和私有访问:

  • 在类扩展中声明您的私有方法(即在类'.m文件顶部附近声明的未命名类别)
  • 在子类标题中声明受保护的方法 - Apple对UIGestureRecognizer使用此模式(请参阅文档和对UIGestureRecognizerSubclass.h的引用)

正如Sachin指出的那样,这些保护措施不是在运行时强制执行的(例如,它们在Java中)。

答案 1 :(得分:45)

  

您既不能声明受保护的私有方法。 Objective-C的动态特性使得无法实现方法的访问控制。 (你可以大量地做到这一点   以严重的速度惩罚修改编译器或运行时,但由于显而易见的原因,这没有完成。)

取自Source

答案 2 :(得分:12)

这是我为了让子类可见的受保护方法而做的,而不要求它们自己实现这些方法。这意味着我的子类中没有得到关于执行不完整的编译器警告。

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.

答案 3 :(得分:9)

我刚发现这个并且它对我有用。为了改进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

答案 4 :(得分:1)

您可以将方法定义为父类的私有方法,并可以在子类中使用[super performSelector:@selector(privateMethod)];

答案 5 :(得分:1)

使用@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

答案 6 :(得分:0)

一种选择是使用类扩展来隐藏方法。

.h

@interface SomeAppDelegate : UIResponder <UIApplicationDelegate>

@property (strong, nonatomic) UIWindow *window;

@end

.m

@interface SomeAppDelegate()
- (void)localMethod;
@end

@implementation SomeAppDelegate

- (void)localMethod
{
}

@end

答案 7 :(得分:0)

您可以排序使用类别执行此操作。

@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所回答的类延续类别,但你必须为每个子类实例重新定义此类别中的方法。

答案 8 :(得分:0)

我通常用内部前缀命名受保护的方法:

let object = {a: 1, b: 4, c: 2, d: 3, e: 10} 
let sum = 0;
const keys = ['a', 'c', 'd', 'e'];

for(let key in object) {
  if(keys.includes(key)) //or key === 'a' || key === 'c' ..
    sum += object[key];
}

console.log(sum);