NSURLSessionTask category method crashes with "Unrecognized selector sent to instance"
Asked Answered
V

3

6

I need to add method to NSURLSessionTask. Here's my category which is supposed to do that:

//  NSURLSessionTask+Extras.h

#import <Foundation/Foundation.h>

@interface NSURLSessionTask (Extras)

- (void)helloNSURLSessionTask;

@end

//  NSURLSessionTask+Extras.m

#import "NSURLSessionTask+Extras.h"

@implementation NSURLSessionTask (Extras)

- (void)helloNSURLSessionTask {
    NSLog(@"hello NSURLSessionTask!");
}

@end

Everything compiles well, autocomplete works, but when I call this method, my application crashes:

2014-06-27 12:32:23.916 Test[4333:60b] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFLocalDataTask helloNSURLSessionTask]: unrecognized selector sent to instance 0x109723310'

Same approach works if I add category to NSObject, and I can't seem to understand why it doesn't for NSURLSessionTask.

Here's a test project which reproduces this problem for me: https://dl.dropboxusercontent.com/u/25100182/Test.zip

Venerable answered 27/6, 2014 at 9:53 Comment(0)
A
5

Unfortunately it doesn't seem that NSURLSession can support categories. I've run into a problem like that trying to add an associated object.
See also here.

Alignment answered 27/6, 2014 at 10:45 Comment(2)
Thanks for the pointer, I'll try what you suggest. By the way, do you think this problem is mentioned somewhere in the docs?Venerable
Nope, I still didn't understand if it's a bug or a "feature"Alignment
T
4

I had similar issue at NSURLSessionDataTask category, when I reduced the scope to NSURLSessionTask it seems to be working correctly.

@interface NSURLSessionTask (iRemoteWallet)
    @property (nonatomic, weak) id context;
@end

Hope this helps.

Towbin answered 9/3, 2015 at 3:42 Comment(0)
A
1

I believe I know what is the origin of this rather odd (to me at least) behaviour. I will provide an example that I've encountered with NSURLSessionDataTask in iOS 9.2.

When you try to use the method that you've added in a category -myMethod: you will see an exception like this:

[__NSCFLocalDataTask -myMethod]: unrecognised selector sent to instance

I've started digging and discovered that __NSCFLocalDataTask class that hides behind our NSURLSessionDataTask class at runtime is just casted to NSURLSessionDataTask but does not inherit from it. This class inheritance chain is __NSCFLocalDataTask : __NSCFLocalSessionTask : __NSCFURLSessionTask : NSObject. So my category does not apply to this class at all. No wonder it is unrecognised.

One solution to this might be to move your category to NSObject and make a bunch of checking. I did it like this:

if ([self respondsToSelector:@selector(response)]) {
    id response = [self performSelector:@selector(response)];

    if ([response isKindOfClass:[NSHTTPURLResponse class]]) {

        return [NSString stringWithFormat:@"%td", ((NSHTTPURLResponse *)response).statusCode];

    }

}

NSException *e =[NSException exceptionWithName:NSInternalInconsistencyException reason:@"errorCode: method should be only used on classes that implement -(NSHTTPURLResponse *)response: method." userInfo:nil];

@throw e;

Ugly? Yes! But it works for now.

Audiphone answered 12/2, 2016 at 9:55 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.