从类别调用方法在 iOS 7.1 中给出 "Unrecognised selector error",但在 8.4 中没问题
Calling method from category gives "Unrecognised selector error" in iOS 7.1, but in 8.4 it's ok
基本上,问题 header 解释了一切。我尝试了很多东西,但都不行。
我有扩展 NSURLSession
的类别,可以处理服务器和网络错误
- (NSURLSessionDataTask *)
dataTaskHandlingErrorsWithRequest:(NSURLRequest *)request
completionHandler:(void (^)(NSData *))completionHandler {
return
[self dataTaskWithRequest:request
completionHandler:^(NSData *data, NSURLResponse *response,
NSError *error) {
if (!error && response &&
[response isKindOfClass:[NSHTTPURLResponse class]]) {
NSHTTPURLResponse *resp = (NSHTTPURLResponse *)response;
if (resp.statusCode / 100 == 2) {
completionHandler(data);
} else {
// Wrong status code from server.
NSNotificationCenter *center =
[NSNotificationCenter defaultCenter];
[center postNotificationName:kPANotifiNameServerStatusError
object:self
userInfo:@{
@"response" : resp
}];
NSLog(@"Wrong status code");
completionHandler(nil);
}
} else {
// Something wrong with network.
NSNotificationCenter *center =
[NSNotificationCenter defaultCenter];
[center postNotificationName:kPANotifiNameNetworkError
object:self
userInfo:@{
@"error" : error ? error : [NSNull null]
}];
NSLog(@"Internet connection problem.");
completionHandler(nil);
}
}];
}
这里是我调用它的地方:
- (void)authenticateWithHandler:(AuthHandler)handler {
NSURLSession *session = [NSURLSession sharedSession];
NSURLSessionTask *task =
[session dataTaskHandlingErrorsWithRequest:self.request
completionHandler:^(NSData *data) {
if (data) {
BOOL suc = [self handleResponse:data];
handler(suc);
} else {
handler(NO);
}
}];
[task resume];
}
因此,在 iOS 7.1 上,如果我调用该方法,它会抛出
2015-08-06 15:29:50.973 MyApp[2618:607] -[__NSCFURLSession dataTaskHandlingErrorsWithRequest:completionHandler:]: unrecognized selector sent to instance 0x7871bf40
2015-08-06 15:29:50.976 MyApp[2618:607] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFURLSession dataTaskHandlingErrorsWithRequest:completionHandler:]: unrecognized selector sent to instance 0x7871bf40'
但在 iOS 8 上有效。我检查了编译源,那里一切正常。
能否查看一下你的分类方法:
if ([self isKindOfClass:[NSURLSession class]]) {
NSLog(@"YES");
}
也许您尝试 运行 它的对象只是被转换为 NSURLSession
而实际上它不是..?只是一些猜测,因为我仍然不知道。
我想在这里指出 Mattt answer,这有助于理解它是如何工作的。
基本上,问题 header 解释了一切。我尝试了很多东西,但都不行。
我有扩展 NSURLSession
的类别,可以处理服务器和网络错误
- (NSURLSessionDataTask *)
dataTaskHandlingErrorsWithRequest:(NSURLRequest *)request
completionHandler:(void (^)(NSData *))completionHandler {
return
[self dataTaskWithRequest:request
completionHandler:^(NSData *data, NSURLResponse *response,
NSError *error) {
if (!error && response &&
[response isKindOfClass:[NSHTTPURLResponse class]]) {
NSHTTPURLResponse *resp = (NSHTTPURLResponse *)response;
if (resp.statusCode / 100 == 2) {
completionHandler(data);
} else {
// Wrong status code from server.
NSNotificationCenter *center =
[NSNotificationCenter defaultCenter];
[center postNotificationName:kPANotifiNameServerStatusError
object:self
userInfo:@{
@"response" : resp
}];
NSLog(@"Wrong status code");
completionHandler(nil);
}
} else {
// Something wrong with network.
NSNotificationCenter *center =
[NSNotificationCenter defaultCenter];
[center postNotificationName:kPANotifiNameNetworkError
object:self
userInfo:@{
@"error" : error ? error : [NSNull null]
}];
NSLog(@"Internet connection problem.");
completionHandler(nil);
}
}];
}
这里是我调用它的地方:
- (void)authenticateWithHandler:(AuthHandler)handler {
NSURLSession *session = [NSURLSession sharedSession];
NSURLSessionTask *task =
[session dataTaskHandlingErrorsWithRequest:self.request
completionHandler:^(NSData *data) {
if (data) {
BOOL suc = [self handleResponse:data];
handler(suc);
} else {
handler(NO);
}
}];
[task resume];
}
因此,在 iOS 7.1 上,如果我调用该方法,它会抛出
2015-08-06 15:29:50.973 MyApp[2618:607] -[__NSCFURLSession dataTaskHandlingErrorsWithRequest:completionHandler:]: unrecognized selector sent to instance 0x7871bf40
2015-08-06 15:29:50.976 MyApp[2618:607] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFURLSession dataTaskHandlingErrorsWithRequest:completionHandler:]: unrecognized selector sent to instance 0x7871bf40'
但在 iOS 8 上有效。我检查了编译源,那里一切正常。
能否查看一下你的分类方法:
if ([self isKindOfClass:[NSURLSession class]]) {
NSLog(@"YES");
}
也许您尝试 运行 它的对象只是被转换为 NSURLSession
而实际上它不是..?只是一些猜测,因为我仍然不知道。
我想在这里指出 Mattt answer,这有助于理解它是如何工作的。