美文网首页iOS DeveloperiOS 开发
Category真的那么靠谱吗?

Category真的那么靠谱吗?

作者: 三角君 | 来源:发表于2016-03-06 13:23 被阅读329次

    Category是我们在平常写代码时,必然会使用到的一种技术,它有诸多好处:

    1. 将一个很大的类拆分成相对独立的功能类
    2. 替换原来的函数
      ....

    例如:

    @interface XPMainViewController (AutoLogin)
    
    - (void)autoLogin;
    
    @end
    
    @interface XPMainViewController (SyncConfig)
    
    - (void)syncRemoteConfig;
    
    @end
    

    看起来Category真的非常不错,可以帮我们模块化
    清晰化我们的代码,但是它真的靠谱吗?我们来验证一下。

    首先,我们先创建一个NSURLSessionTask的Category:

    @interface NSURLSessionTask (Test)
    
    - (NSString*)testName;
    
    @end
    
    @implementation NSURLSessionTask (Test)
    
    - (NSString*)testName {
        return @"test";
    }
    
    @end
    

    Category很简单,就是给NSURLSessionTask增加了一个叫testName的函数!

    然后我们来调用一下试试:

    NSURLSessionTask *task = [[NSURLSession sharedSession] dataTaskWithURL:[NSURL URLWithString:@"http://www.baidu.com"]];
    NSLog(@"%@",[task testName]);
    

    代码写到这,我们满怀信心的Commnd+r,但是令人意想不到的事情发生了,我们的程序crash了,堆栈显示为:

    **2016-03-06 13:11:13.806 URLSessionTest[2704:94286] -[__NSCFLocalDataTask testName]: unrecognized selector sent to instance 0x7fa25a5f8e10**
    

    呵呵,看堆栈的信息提示,这个crash引起的原因是:没有testName函数啊!!!!

    Oh,my god!什么玩意,我不是已经使用Category技术为NSURLSessionTask增加了这个函数了吗?怎么还是没有提示无实现呢?

    等等,我们再仔细看看。什么!!!__NSCFLocalDataTask无testName实现!这是什么玩意,我明明代码写的是NSURLSessionTask啊!怎么回事???WTF

    咦,难道NSURLSession返回的不是NSURLSessionTask???不得已,log下class、supperclass等等看看。

    NSURLSessionTask *task = [[NSURLSession sharedSession] dataTaskWithURL:[NSURL URLWithString:@"http://www.baidu.com"]];
    NSLog(@"%@", [task class]);
    NSLog(@"%@", [task superclass]);
    NSLog(@"%@", [[task superclass] superclass]);
    NSLog(@"%@", [[[task superclass] superclass] superclass]);
    

    得到结果:

    **2016-03-06 13:11:13.805 URLSessionTest[2704:94286] __NSCFLocalDataTask**
    **2016-03-06 13:11:13.806 URLSessionTest[2704:94286] __NSCFLocalSessionTask**
    **2016-03-06 13:11:13.806 URLSessionTest[2704:94286] __NSCFURLSessionTask**
    **2016-03-06 13:11:13.806 URLSessionTest[2704:94286] NSURLSessionTask**
    

    在iOS9下,得到这些结果,并且iOS7下还不是这个结果,WTF!!!

    但是好歹原因总算是找到了:NSURLSession的dataTaskWithURL返回的是一个private class,压根就不是NSURLSessionTask,它的superClass的superClass的superClass才是NSURLSessionTask!好长的继承链...

    一次意外的debug,也获得了一个意外的收货。

    其实Category这个技术和这次的crash没有直接关系,😄。可以说这是Apple留的坑吧。

    相关文章

      网友评论

        本文标题:Category真的那么靠谱吗?

        本文链接:https://www.haomeiwen.com/subject/fidakttx.html