有什么原因会导致 isKindOfClass 的返回结果有问题?

2015-11-13 23:02:54 +08:00
 mogutouer

偶尔知道了 FXForms ,正打算在项目里试一下的时候,发现会报错但原 sample 没有问题,我把 sample 没有改动的复制过来之后还是报错,本来不太在意以为是 FXForms 的 bug 什么的,我认真地找到了出错的位置,深究之后发现一个非常奇怪的现象。

下面这段代码:

id valueClass = [NSString class];
if ([valueClass isKindOfClass:[NSString class]])
{
    NSLog(@"YES YES YES");
}else{
    NSLog(@"NO NO NO");
}

正常来说,输出的结果应该是 NO NO NO,因为 valueClass 是一个 Class ,并不是 NSString 。

可怕的是,在我的项目里,输出的居然是 YES YES YES,我意识到这非常不对,虽然目前并没有什么影响,但以后肯定会有奇奇怪怪的 bug 出现,我找了好几天都没有结果,公司的项目没办法完整的传上来,大致是用了 cocoapods , pods 也是几个常用的而已,就是一个普通的项目而已。
我怕是我 SDK 的问题,新建了一个项目,输出的结果是 NO NO NO,这更让我觉得奇怪。

所以上来跟大家集思广益一下,究竟是什么原因,会导致 isKindOfClass 方法的结果异常呢?

3522 次点击
所在节点    iDev
7 条回复
SeanChense
2015-11-13 23:08:10 +08:00
Generally isKindOfClass: is not safe to use to test for membership. If an instance returns YES for isKindOfClass:[NSString class], you know only that it will respond to all methods defined in the NSString class, but you will not know for sure what the implementation of those methods might do. Someone might have subclassed NSString to raise an exception for the length method.

http://stackoverflow.com/questions/1096772/is-it-safe-to-use-iskindofclass-against-an-nsstring-instance-to-determine-type
mogutouer
2015-11-13 23:29:44 +08:00
@SeanChense

我尝试根据这个回答,尝试了一下用 isMemberOfClass ,发现 NSString 有时候的 class 是 __NSCFConstantString 什么的, NSDictionary 的变量有时候 class 是 __NSDictionaryI 之类,没法正确的判断类型。

我奇怪的是,把主贴那段代码写在 didFinishLaunchingWithOptions 里, AppDelegate 其他的代码全都注释掉包括#import 的东西都注释掉,输出的结果还是 `YES YES YES`,我逐条对比过跟新项目的 Build Settings ,除了证书外,全都一样。

只是这段代码,应该不存在结果有 runtime 影响的异常啊
sojingle
2015-11-14 02:00:38 +08:00
看文档,- isKindOfClass: 最后一句
> If the receiver is a class object, this method returns YES if aClass is a Class object of the same type, NO otherwise.
pheyer
2015-11-14 09:25:56 +08:00
楼主需要研究一下这篇文章: http://chun.tips/blog/2014/11/05/bao-gen-wen-di-objective%5Bnil%5Dc-runtime-(2)%5Bnil%5D-object-and-class-and-meta-class/
zhangmeteor
2015-11-14 09:58:51 +08:00
iskindofClass 是比较 isa ,而 xxx class 的 isa 走的是 meta class 的线路一路 super 上去最终由于 NSObject 原类的 isa 指向 NSObject ,所以最终和你比较的对象一路 super class 到 NSObject 汇合到了一起,所以就成了 YES
mogutouer
2016-05-01 00:11:32 +08:00
大家好,偶然我找到原因了,有点走近科学。

是因为我用了一个叫 tuSDK 的轮子,这货有一个 Category ,特么居然覆盖了 isKindOfClass ,同名。导致 isKindOfClass 其实是用他自定义类里的方法,深度测试了一下这货除了判断是不不是他写的那些 Class 外,都返回 NSString ,坑爹。
IdealHack
2016-06-13 10:40:50 +08:00
@mogutouer 您好,我是 TuSDK 技术对接负责人,抱歉给您带来不便。我们曾经修复过这个问题,请问在较新版本上您还会遇到吗?

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/236073

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX