类别在运行时不可用的 CocoaPod

CocoaPod with category not available at runtime

我知道有同样的问题 already been posted,但我想我遇到了另一个问题。

我创建了名为 NSURLSession+PromiseKit 的 CocoaPod 以允许将 PromiseKit 与 NSURLSession 一起使用。

我有定义:

@implementation NSURLSession (PromiseKit)

- (PMKPromise *)promiseDataTaskWithURL:(NSURL *)url {
    return [PMKPromise ...];
}

@end

代码示例:

NSURLSession *session = [NSURLSession sharedSession];
NSURL *url = [NSURL URLWithString:@"..."];
[session promiseDataTaskWithURL:url].then( ^(NSData *data) {
    NSLog(@"Result: %@", data);
}).catch( ^(NSError *e) {
    NSLog(@"Error: %@", e);
});

适用于 iOS 8,但不适用于 iOS 7。我收到此错误:

Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFURLSession promiseDataTaskWithURL:]: unrecognized selector sent to instance 0x7c236720'

现在当然我虽然没有加载类别所以我将此行添加到 podspec 以确保代码已加载:

s.xcconfig = { 'OTHER_LDFLAGS' => '-ObjC -all_load' }

但效果并不好

所以我在 category file 中添加了一行:

+ (void)load {
    NSLog(@"loaded");
}

令我惊讶的是 load 方法被调用了,这意味着代码确实被加载了。那么为什么加载代码执行时找不到category方法?

好的,一如既往,发布问题会引导我找到答案。

已经found NSURLSession 不支持类别。

  • 在iOS7中,底层NSURLSessionclass为__NSCFURLSession,不支持分类
  • 在iOS8中,底层class是__NSURLSessionLocal,它确实支持类别。

我的解决方案,虽然令人畏惧,但替换为:

@implementation NSURLSession (PromiseKit)

作者:

@implementation NSObject (PromiseKit)

仅在实现文件上。这将防止 Pod 用户错误地将方法与 NSURLSession 对象以外的对象一起使用。不过,不妨碍他玩其他把事情搞砸的把戏……