使用cocoapods中的库,我想覆盖一些私有方法而不会弄乱库。
ClassInLibrary.h
@interface ClassInLibrary : UIView
- (void)publicMethod;
@end
ClassInLibrary.m
@interface ClassInLibrary ()
@property BOOL privateBoolean;
@end
@implementation ClassInLibrary
- (void)privateMethod {
...
}
- (void)publicMethod {
...
self.privateBoolean = YES;
[self privateMethod];
}
@end
我要做的是创建ClassInLibrary
的子类并覆盖publicMethod
。但是,由于aBoolean
和privateMethod
不可见,是否有任何方法可以覆盖publicMethod
,因为我需要使用它们?
Subclass.m
@interface Subclass ()
@end
@implementation Subclass
- (void)publicMethod {
...
self.privateBoolean = NO; // cannot access
[self privateMethod]; // cannot access
}
@end
编辑:
我同意@Anoop Vaidya,调用私有API不是一个好主意。真实案例是公共方法中的硬编码字符串,我想修改它。
Superclass.m
- (void)publicMethod {
...
[self privateMethod];
...
NSString *string = @"a string";
[self doSomeThingWithTheString]; // private
...
}
我无法使用[super publicMethod]
,因为它会再次调用privateMethod
。
可能有更好,更安全的方法来实现这一目标吗?
答案 0 :(得分:4)
您可以执行以下操作,但不应该这样做。
您可以使用选择器调用私有方法,但它会显示一条警告,您可以禁用它。
SEL selector = NSSelectorFromString(@"privateMethod");
if ([a respondsToSelector:selector]) {
NSLog(@"yes privateMethod exists");
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Warc-performSelector-leaks"
[self performSelector:selector];
#pragma clang diagnostic pop
}
答案 1 :(得分:2)
您可以使用在子类中定义但在超类上定义的类别,以使属性和方法定义对子类可见。现在,您可以覆盖公共方法并使用私有部分。
你仍需要小心,如果将来更改/移动/重命名私有部分,你的代码将编译得很好。因此,在执行此类操作时,您的代码应该是防御性的,并产生有意义的错误,以便您知道发生了什么。同时确保单位/回归测试涵盖此区域。