【问题标题】:unrecognized selector when calling method defined in class extension调用类扩展中定义的方法时无法识别的选择器
【发布时间】:2013-08-31 04:53:05
【问题描述】:

我有一个类,我在头文件中定义一个类扩展,如下所示:

@interface GCFriend : GCDataObject

@property (nonatomic, strong) NSString *firstName;
...
...
...    

+ (NSOperation *)getFriendsCached:(void (^)(NSArray *cached))cached
                            fresh:(void (^)(BOOL success, NSArray *fresh))fresh;    
@end

@interface GCFriend (Transient)

@property (nonatomic, strong) UIImage *image;

@end

现在,作为一个偏好问题,我希望将该图像属性与主接口声明分开,因为它不是来自 api 的东西。但是,当我以这种方式声明它时,当我调用 getter 方法时会得到一个无法识别的选择器。这是为什么?如果我将其移至主界面声明,则没有问题。

【问题讨论】:

    标签: ios objective-c


    【解决方案1】:

    这不是类扩展。那是一个类别。类扩展通常放在类的实现文件中,格式为@interface GCFriend () — 空括号。您可以在类扩展中添加实例变量,但不能在类别中添加。 (这是因为类扩展是作为类的一部分编译的,而类别是单独编译和加载的。)

    【讨论】:

    • 注意:我不相信你可以在为 32 位 OSX 编译时在类扩展中添加实例变量。
    • @trojanfoe:是的,这是真的。而且实例变量综合在遗留运行时根本不起作用。
    • 你的意思是@synthesize filename = _filename;?我没有遇到过这个问题。
    • @trojanfoe:具体来说,除非您在类的 @interface 块中声明了 _filename 实例变量,否则该行将无法在旧版运行时运行。
    • 哦,好吧,这就是为什么我从来没有遇到过这个问题,因为我相信这是一个“有用的功能”,最终会以几次击键为代价对开发人员产生反作用。为信息干杯。
    【解决方案2】:

    这很有趣。确实应该有警告。我猜这是因为属性的隐式合成,但不能对类别中声明的属性起作用。

    无论如何,您可以保持头文件不变,但您必须在 .m 文件中显式编写属性 getter 和 setter。

    ...
    @interface GCFriend() {
        UIImage *image; // create the ivar 
    }
    @end
    
    @implementation GCFriend (Transient) 
    
    - (UIImage *) image {  // getter
        return image ;
    }
    
    - (void) setImage:(UIImage *) img { // setter
        image = img ;
    }
    @end
    

    【讨论】:

      猜你喜欢
      • 2014-11-22
      • 2012-05-12
      • 2012-05-13
      • 1970-01-01
      • 1970-01-01
      • 2011-02-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多