V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
iOS 开发实用技术导航
NSHipster 中文版
http://nshipster.cn/
cocos2d 开源 2D 游戏引擎
http://www.cocos2d-iphone.org/
CocoaPods
http://cocoapods.org/
Google Analytics for Mobile 统计解决方案
http://code.google.com/mobile/analytics/
WWDC
https://developer.apple.com/wwdc/
Design Guides and Resources
https://developer.apple.com/design/
Transcripts of WWDC sessions
http://asciiwwdc.com
Cocoa with Love
http://cocoawithlove.com/
Cocoa Dev Central
http://cocoadevcentral.com/
NSHipster
http://nshipster.com/
Style Guides
Google Objective-C Style Guide
NYTimes Objective-C Style Guide
Useful Tools and Services
Charles Web Debugging Proxy
Smore
mogutouer
V2EX  ›  iDev

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

  •  
  •   mogutouer · 2015-11-13 23:02:54 +08:00 · 3526 次点击
    这是一个创建于 3328 天前的主题,其中的信息可能已经有所发展或是发生改变。

    偶尔知道了 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 方法的结果异常呢?

    7 条回复    2016-06-13 10:40:50 +08:00
    SeanChense
        1
    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
        2
    mogutouer  
    OP
       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
        3
    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
        4
    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
        5
    zhangmeteor  
       2015-11-14 09:58:51 +08:00 via iPhone
    iskindofClass 是比较 isa ,而 xxx class 的 isa 走的是 meta class 的线路一路 super 上去最终由于 NSObject 原类的 isa 指向 NSObject ,所以最终和你比较的对象一路 super class 到 NSObject 汇合到了一起,所以就成了 YES
    mogutouer
        6
    mogutouer  
    OP
       2016-05-01 00:11:32 +08:00
    大家好,偶然我找到原因了,有点走近科学。

    是因为我用了一个叫 tuSDK 的轮子,这货有一个 Category ,特么居然覆盖了 isKindOfClass ,同名。导致 isKindOfClass 其实是用他自定义类里的方法,深度测试了一下这货除了判断是不不是他写的那些 Class 外,都返回 NSString ,坑爹。
    IdealHack
        7
    IdealHack  
       2016-06-13 10:40:50 +08:00
    @mogutouer 您好,我是 TuSDK 技术对接负责人,抱歉给您带来不便。我们曾经修复过这个问题,请问在较新版本上您还会遇到吗?
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   985 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 21:56 · PVG 05:56 · LAX 13:56 · JFK 16:56
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.