项目从AFN 2.0 迁移到 3.0,因为代码历史问题,需要通过NSURLSessionTask 获取到responseString,可是通过category 无法添加属性以及方法
由于category 中需要用到reposne 中的数据,所以也无法直接给 NSObject 添加category,各位大大,是否有好的解决方案
拥有18年软件开发和IT教学经验。曾任多家上市公司技术总监、架构师、项目经理、高级软件工程师等职务。 网络人气名人讲师,...
NSURLSessionTask 确实加不了 category,有点类似『不能继承』的问题。一般遇到这种问题有几种思路,你看看对应你的业务能不能用:
组合代替继承,定义一个 NSURLSessionTaskWrapper,里面有一个属性是那个 task,另外想加什么别的属性和方法都可以;用到 task 的部分可以直接用 wrapper.task,也可以写方法透传,比如
wrapper.task
- (NSInteger)someProperty { return self.task.someProperty; }
当然,你控制得了自己的代码用wrapper.task,但控制不了系统的代码,所以我不知道你的业务用不用得了。
用 runtime 加属性、加方法。可以解决上面的『控制不了系统的代码』的问题,用 runtime 改过之后,在系统眼里这个类就多了这些属性、这些方法。不过不能加 category,我不知道 runtime 管用不管用。
外部存储。找找 sessionTask 有没有适合用作唯一 id 的属性,然后写一个 SessionTaskManager 类,新加的方法放在这个 manager 类里面;新加的属性,manager 可以存一个字典,以 sessionTask 的 id 为键,具体的属性为值,需要用到的时候,根据 id 来存取。
以上是几种常用的思路,你可以看看具体到你的业务是否适用~
2016年06月03日21:29:15 更新
因为 http://stackoverflow.com/a/35359533 提到的原因,所以将扩展添加到NSObject类 因为某些原因,请不要在文件中只添加一个分类。详细原因可以移步到 https://developer.apple.com/library/mac/qa/qa1490/_index.html 查看。
因为 http://stackoverflow.com/a/35359533 提到的原因,所以将扩展添加到NSObject类
NSObject
因为某些原因,请不要在文件中只添加一个分类。详细原因可以移步到 https://developer.apple.com/library/mac/qa/qa1490/_index.html 查看。
@interface NSObject (sun) - (void)_sun_setResponseString:(NSString *)responseString; - (NSString *)_sun_responseString; @end @implementation NSObject (sun) static int _sun_ResponseStringKey; - (void)_sun_setResponseString:(NSString *)responseString { objc_setAssociatedObject(self, &_sunResponseStringKey, responseString, OBJC_ASSOCIATION_RETAIN_NONATOMIC); } - (NSString *)_sun_responseString { return objc_getAssociatedObject(self, &_sunResponseStringKey); } @end
[_sessionManager setDataTaskDidReceiveDataBlock:^(NSURLSession *_Nonnull session, NSURLSessionDataTask *_Nonnull dataTask, NSData *_Nonnull data) { [dataTask _sun_setResponseString:[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]]; NSLog(@"%@", [dataTask _sun_responseString]); }];
题主可以看看上面的代码是否可以实现需求。
NSURLSessionTask 确实加不了 category,有点类似『不能继承』的问题。一般遇到这种问题有几种思路,你看看对应你的业务能不能用:
组合代替继承,定义一个 NSURLSessionTaskWrapper,里面有一个属性是那个 task,另外想加什么别的属性和方法都可以;用到 task 的部分可以直接用
wrapper.task
,也可以写方法透传,比如当然,你控制得了自己的代码用
wrapper.task
,但控制不了系统的代码,所以我不知道你的业务用不用得了。用 runtime 加属性、加方法。可以解决上面的『控制不了系统的代码』的问题,用 runtime 改过之后,在系统眼里这个类就多了这些属性、这些方法。不过不能加 category,我不知道 runtime 管用不管用。
外部存储。找找 sessionTask 有没有适合用作唯一 id 的属性,然后写一个 SessionTaskManager 类,新加的方法放在这个 manager 类里面;新加的属性,manager 可以存一个字典,以 sessionTask 的 id 为键,具体的属性为值,需要用到的时候,根据 id 来存取。
以上是几种常用的思路,你可以看看具体到你的业务是否适用~
2016年06月03日21:29:15 更新
题主可以看看上面的代码是否可以实现需求。