Category真的那么靠谱吗?

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真的那么靠谱吗?)