我刚刚遇到了非常奇怪的问题。在我目前的项目中,我正在处理复杂的视图并在运行中进行一些修改。
e.g。如果视图响应setTextColor,则使用以下代码
设置新颜色if ([view respondsToSelector:propertySelector]) {
// Invoke method.
}
意外调用方法返回UIButtonLabel
(私有隐藏的
UIKit
)中的类,并执行上面的方法。在上面的代码中UIButtonLabel
回复了
setTextColor:
然后应用程序在调用中崩溃了。
如何避免UIKit
私人课程的意外访问和调用?
答案 0 :(得分:0)
是的,您可以遍历从NSObject
开始到您的班级的反向超类链,检查您的方法不属于class_copyMethodList
当前已检查的类及其元类(对于类)方法)。在执行此操作时,请检查当前检查的课程是否不是来自[NSBundle mainBundle]
([NSBundle bundleForClass:]
),您可以终止搜索 - 您已经到达了代码。但是,正如您可以想象的那样,即使使用缓存,它也是真正缓慢的做事方式。
重新设计代码可能会更好:尝试使用conformsToProtocol:
代替respondsToSelector
。例如,您声明一个协议
@protocol XYZSettableColor <NSObject>
@required
- (void)setSomethingWithColor:(UIColor *)textColor;
@end
然后,在您的类(类)中,您要声明它符合协议(并且显然实现了所需的方法)
@interface XYZMyControl : UIControl <XYZSettableColor>
@end
然后,当你想确保传递的组件有资格执行指定的方法时:
- (void)applyTextColor:(UIColor *)color toControl:(id)control {
if ([control conformsToProtocol:@protocol(XYZSettableColor)]) {
[(id<XYZSettableColor>)control setSomethingWithColor:color];
}
}
答案 1 :(得分:-1)
我认为100%肯定无法检查这一点。 您必须知道objective-c适用于方法调用,这意味着没有真正的私有方法。 (至少,任何人都可以调用&#34;私有&#34;方法)。
为防止调用此类方法,您应该避免使用&#34; performSelector&#34;以及您不熟悉的选择器的其他调用方法。
此外,在app-submition过程中存在一个安全措施。在submition过程结束时,如果您使用了&#34; risky&#34;选择器或具有Apple知道的名称的方法调用&#34;在私有API&#34;中使用的方法,然后会出现警告,告诉您在哪里使用了私有API。
所以最后,在提交过程结束时一切都应该没问题。