Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

关于Unrecognized Selector防护的疑问 #1

Open
AironMore opened this issue May 9, 2017 · 11 comments
Open

关于Unrecognized Selector防护的疑问 #1

AironMore opened this issue May 9, 2017 · 11 comments

Comments

@AironMore
Copy link

Hello, 我在阅读代码的时候发现防护之后都调用的 baymaxProtected 方法,这个方法的返回值为空,那如果我需要防护的是有返回值(如CGFloat)这样的,这个方法会不会有问题呢?

@ParsifalC
Copy link
Owner

@AironMore 有问题指的是哪些方面呢?关于Unrecognized Selector类型的防护,这里处理只是转发消息到一个特定的类。如果问题指的是被转发消息后出现的业务异常,那确实可能会有问题。

@ParsifalC
Copy link
Owner

另外,再次声明下,这个repo只是网易防护方案的预演实现,代码写得比较混乱,可能还存在各种问题,不可用作正式工程项目。

@AironMore
Copy link
Author

恩 之前想的问题是 “比如我有个有返回值的方法在.h声明,.m中忘记实现,其他地方正常使用是否会崩溃?” 刚才 试了下是不会崩溃的。demo对于学习runtime很好用!

@ParsifalC
Copy link
Owner

嗯,这种情况下直接调用这个方法是不会有问题的。但你如果依赖这个返回值,再拿返回值去做一些业务逻辑的话,就可能会出现问题了。

@AironMore
Copy link
Author

是的 业务逻辑是没办法cover住的

@gonghongxia
Copy link

Unrecognized Selector类型的防护相关问题:

NSString *string = @(6); // 运行时,对象类型为NSNumber。
if (string.length > 0) {
NSLog(@"执行到这了,一切正常");
} else {
NSLog(@"未出错");
}

对于以上代码,在调用length方法时,就会出错。去掉![NSObject isMainBundleClass:[self class]],就会给系统方法也添加保护。保护范围只局限于项目代码和静态库,是出于什么考虑呢?

@ParsifalC
Copy link
Owner

有以下考虑:

  1. 系统的类出错概率较小;
  2. 系统的类中有部分都是依赖于消息转发机制的;
  3. 对于比较常出错的系统类,可以提供黑白名单机制,加到防护列表中;

最后补充一下,其实demo里防护的只是mainBundle的类,对于pod中集成的是不做防护的,如果需要的话,可以使用以下方法:

+ (BOOL)isCustomClass:(Class)cls {
    ///var/containers/Bundle/Application/CB0D354B-DD08-4845-A084-A22FF01097FE/WYCrashDoctor_Example.app
    NSString *mainBundlePath = [NSBundle mainBundle].bundlePath;
    ///var/containers/Bundle/Application/CB0D354B-DD08-4845-A084-A22FF01097FE/WYCrashDoctor_Example.app/Frameworks/WYCrashDoctor.framework
    NSString *clsBundlePath = [NSBundle bundleForClass:cls].bundlePath;
    
    return cls && mainBundlePath && clsBundlePath && [clsBundlePath hasPrefix:mainBundlePath];
}

@gratefulHeart
Copy link

@gonghongxia 遇到的问题怎么解决呢

@ParsifalC
Copy link
Owner

@gratefulHeart 什么问题呢?

@gratefulHeart
Copy link

@ParsifalC 和gonghongxia遇到同样的问题

@ParsifalC
Copy link
Owner

@gratefulHeart 哦,这个问题在 @gonghongxia 和我的评论里也说了。demo里是特地判断了是不是在main bundle里的类。如果你想测试系统类的,把判断代码去掉就好了。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants