Метод категории NSURLSessionTask аварийно завершает работу с нераспознанным селектором, отправленным в экземпляр

Мне нужно добавить метод в NSURLSessionTask. Вот моя категория, которая должна это делать:

//  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

Все компилируется хорошо, автозаполнение работает, но когда я вызываю этот метод, мое приложение вылетает:

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'

Тот же подход работает, если я добавляю категорию к NSObject, и я не могу понять, почему этого не происходит для NSURLSessionTask.

Вот тестовый проект, который воспроизводит эту проблему для меня: https://dl.dropboxusercontent.com/u/25100182/Test.zip


person Andrii Chernenko    schedule 27.06.2014    source источник


Ответы (3)


К сожалению, похоже, что NSURLSession не может поддерживать категории. Я столкнулся с такой проблемой, пытаясь добавить связанный объект.
См. также здесь.

person Andrea    schedule 27.06.2014
comment
Спасибо за подсказку, попробую то, что вы предлагаете. Кстати, как вы думаете, эта проблема упоминается где-нибудь в документах? - person Andrii Chernenko; 27.06.2014
comment
Неа, я так и не понял, баг это или фича - person Andrea; 27.06.2014

У меня была аналогичная проблема в категории NSURLSessionDataTask, когда я уменьшил область до NSURLSessionTask, похоже, она работает правильно.

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

Надеюсь это поможет.

person Ramesh    schedule 09.03.2015

Мне кажется, я знаю, каково происхождение этого довольно странного (по крайней мере для меня) поведения. Я приведу пример, с которым я столкнулся с NSURLSessionDataTask в iOS 9.2.

Когда вы попытаетесь использовать метод, который вы добавили в категорию -myMethod:, вы увидите такое исключение:

[__NSCFLocalDataTask -myMethod]: в экземпляр отправлен нераспознанный селектор

Я начал копать и обнаружил, что класс __NSCFLocalDataTask, который во время выполнения скрывается за нашим классом NSURLSessionDataTask, просто приводится к типу NSURLSessionDataTask, но не наследуется от него. . Это цепочка наследования классов: __NSCFLocalDataTask : __NSCFLocalSessionTask : __NSCFURLSessionTask : NSObject. Так что моя категория вообще не относится к этому классу. Неудивительно, что его не узнают.

Одним из решений этого может быть перемещение вашей категории в NSObject и выполнение нескольких проверок. Я сделал это так:

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;

Уродливый? Да! Но пока это работает.

person NKorotkov    schedule 12.02.2016