iOS:在运行时找不到NSURLSession类别方法
我想在NSURLSession上创建一个类别。应用程序编译正常,但当我尝试调用category方法时iOS:在运行时找不到NSURLSession类别方法,ios,categories,nsurlsession,Ios,Categories,Nsurlsession,我想在NSURLSession上创建一个类别。应用程序编译正常,但当我尝试调用category方法时 -[__NSCFURLSession doSomething]: unrecognized selector sent to instance 0xbf6b0f0 <unknown>:0: error: -[NSURLSession_UPnPTests testCategory] : -[__NSCFURLSession doSomething]: unrecognized sele
-[__NSCFURLSession doSomething]: unrecognized selector sent to instance 0xbf6b0f0
<unknown>:0: error: -[NSURLSession_UPnPTests testCategory] : -[__NSCFURLSession doSomething]: unrecognized selector sent to instance 0xbf6b0f0
-[\uu NSCFURLSession doSomething]:发送到实例0xbf6b0f0的无法识别的选择器
:0:错误:-[NSURLSession\u UPnPTests testCategory]:-[\uu NSCFURLSession doSomething]:发送到实例0xbf6b0f0的选择器无法识别
非常奇怪,这里有一个我构建的测试类来展示这个问题。NSString上的类别工作正常,但NSURLSession上的类别在运行时找不到该方法。我怀疑这是内在的
请发表意见:-)
#导入
@接口字符串(测试)
-(无效)doSomethingHere;
@结束
@实现NSString(测试)
-(无效)doSomethingHere{
NSLog(@“Hello字符串”);
}
@结束
@接口会话(测试)
-(无效)剂量测定;
@结束
@实现NSURLSession(测试)
-(无效)剂量{
NSLog(@“你好!!!!”);
}
@结束
@接口NSURLSession\u UPnPTests:XCTestCase
@结束
@实现NSURLSession_UPnPTests
-(无效)测试类别{
[@“abc”doSomethingHere];
NSURLSession*会话=[NSURLSession sharedSession];
[会议记录];
}
@结束
您必须在调用自定义方法的地方导入自定义类别
#import "NSURLSession+test.h"
我对background
NSURLSessionUploadTask
s也有类似的结果,在-URLSession:task:didcompletewitheror:
委托回调期间,将其反序列化为\NSCFURLSessionUploadTask
s
如果我是你,我会放弃这种方法,使用合成(即使nsursession
成为另一个对象中的ivar)。如果需要使用NSURLSession
存储一些信息,可以将JSON编码的字典塞进.sessionDescription
以下是我用于执行任务的代码:
#pragma mark - Storing an NSDictionary in NSURLSessionTask.description
// This lets us attach some arbitrary information to a NSURLSessionTask by JSON-encoding
// an NSDictionary, and storing it in the .description field.
//
// Attempts at creating subclasses or categories on NSURLSessionTask have not worked out,
// because the –URLSession:task:didCompleteWithError: callback passes an
// __NSCFURLSessionUploadTask as the task argument. This is the best solution I could
// come up with to store arbitray info with a task.
- (void)storeDictionary:(NSDictionary *)dict inDescriptionOfTask:(NSURLSessionTask *)task
{
NSData *data = [NSJSONSerialization dataWithJSONObject:dict options:0 error:nil];
NSString *stringRepresentation = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
[task setTaskDescription:stringRepresentation];
[stringRepresentation release];
}
- (NSDictionary *)retrieveDictionaryFromDescriptionOfTask:(NSURLSessionTask *)task
{
NSString *desc = [task taskDescription];
if (![desc length]) {
DDLogError(@"No description for %@", task);
return nil;
}
NSData *data = [desc dataUsingEncoding:NSUTF8StringEncoding];
NSDictionary *dict = (data ? (id)[NSJSONSerialization JSONObjectWithData:data options:0 error:nil] : nil);
if (!dict) {
DDLogError(@"Could not parse dictionary from task %@, description\n%@", task, desc);
}
return dict;
}
如果您真的想向NSURLSession添加类别,这里有一个替代解决方案。我从中找到了这个解决方案。当然,您必须非常小心名称,以避免名称冲突 标题代码
#import <Foundation/Foundation.h>
@interface NSURLSession (YTelemetry)
-(void) hello;
@end
现在在代码中,我可以
NSURLSession *session = [NSURLSession sharedSession];
[session hello];
我尝试了与@clay bridges相同的方法(即为每个任务存储一个userInfo
NSDictionary
),并且在会话配置不同于后台的情况下使用NSURLSession
时效果非常好。如果您将nsursession
与后台配置一起使用,并且您的应用程序被终止或崩溃,则上传/下载将在后台继续,由操作系统管理。上传/下载完成后,如果我试图检索以前存储的userInfoNSDictionary
,我将一无所获。我的解决方案是使用NSURLProtocol
:+setProperty将该自定义对象/NSDictionary
存储在请求中,而不是任务中:福基:inRequest:
,稍后,使用以下方法检索信息:
id customObject=[NSURLProtocol propertyworkey:@“yourkey”inRequest:sessionTask.originalRequest]代码>是的。我已经写过作文了。但我仍然对根本原因感到好奇。臭虫报告给苹果。你有没有发现更多关于这个问题的信息?我也有同样的问题。苹果公司对你的错误报告有何回应?如果可能的话,我想使用一个类别。@drekka:你能在苹果论坛上发布bug链接吗?甚至我也面临着类似的问题,除了在iOS7中,我无法从任何地方调用任何自定义的NSURLSession子类/类别方法。它在>=iOS8中运行良好。请让我知道,如果你能帮助我无论如何。问题是NSull会话对象正在转换为他们的核心基础对应。使用这种方法仍然不允许您在category方法中与self对象交互。@jqyao他在代码中已经提到,我们不能在NSURLSession上创建category,所以请在NSObject上创建category。这是一个相当大的技巧,但确实有效。要访问category方法中的NSURLSession方法,请验证该对象是否为NSURLSession,然后创建一个将self类型转换为NSURLSession的局部变量。您可以在方法前加前缀,例如-(void)jq_hello
#import "NSURLSession+YTelemetry.h"
@implementation NSObject (YTelemetry)
-(void) hello
{
NSLog(@"hello world");
}
@end
NSURLSession *session = [NSURLSession sharedSession];
[session hello];