可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I wanted to create a category on NSURLSession. The app compiles ok, but when I attempt to call the category methods I get
-[__NSCFURLSession doSomething]: unrecognized selector sent to instance 0xbf6b0f0 :0: error: -[NSURLSession_UPnPTests testCategory] : -[__NSCFURLSession doSomething]: unrecognized selector sent to instance 0xbf6b0f0
Very strange, here is a test class I built to show the issue. The category on the NSString works fine, but the category on NSURLSession fails to find the method at runtime. I suspect this is something internal.
Opinions please :-)
#import @interface NSString (test) -(void) doSomethingHere; @end @implementation NSString (test) -(void) doSomethingHere { NSLog(@"Hello string"); } @end @interface NSURLSession (test) -(void) doSomething; @end @implementation NSURLSession (test) -(void) doSomething { NSLog(@"Hello!!!!"); } @end @interface NSURLSession_UPnPTests : XCTestCase @end @implementation NSURLSession_UPnPTests -(void) testCategory { [@"abc" doSomethingHere]; NSURLSession *session = [NSURLSession sharedSession]; [session doSomething]; } @end
回答1:
I've had similar results with backgrounded NSURLSessionUploadTask
s, which get deserialized as __NSCFURLSessionUploadTask
s during the -URLSession:task:didCompleteWithError:
delegate callback.
If I were you, I'd give up on that approach, and use composition (i.e. make the NSURLSession
an ivar in another object). If you need to store some info with the NSURLSession
, you could stuff a JSON-encoded dictionary into the .sessionDescription
.
Here's the code that I used to do that for a task:
回答2:
Here is an alternative solution if you really want to add category to NSURLSession. I found this solution from BETURLSession. Of course, you have to be really careful about the name to avoid name conflicting.
Code for header
#import @interface NSURLSession (YTelemetry) -(void) hello; @end
Code for implementation
#import "NSURLSession+YTelemetry.h" @implementation NSObject (YTelemetry) -(void) hello { NSLog(@"hello world"); } @end
Now in the code, I can
NSURLSession *session = [NSURLSession sharedSession]; [session hello];
回答3:
I tried to do the same as @clay-bridges (i.e. storing a userInfo NSDictionary
for each task), and it works great when using a NSURLSession
with a session configuration different from background. If you use a NSURLSession
with a background configuration, and your app is terminated or crashes, the upload/download continues in the background, managed by the OS. When the upload/download finishes, if I try to retrieve the userInfo NSDictionary
previously stored, I get nothing. My solution is to store that custom object/NSDictionary
in the request, not the task, using NSURLProtocol
:
, and later on, retrieve the information using:
id customObject = [NSURLProtocol propertyForKey:@"yourkey" inRequest:sessionTask.originalRequest];
回答4:
you must import the your custom category where you call the custom methods
#import "NSURLSession+test.h"