【问题标题】:iOS category conforms to a protocol with properties: how to implementiOS 类符合带有属性的协议:如何实现
【发布时间】:2013-12-23 21:43:16
【问题描述】:

我在我创建的一个类上有一个类别,并且该类别符合协议,该协议在其实现中需要一个属性。但是,因为我在一个类别中,所以我无法在类别的实现中综合属性。因此,我对如何实现 setter 方法感到困惑(当我将协议的属性保持为只读时,它可以正常工作,因为我只需要一个访问器方法)。

这是我的协议:

@protocol SomeProtocol <NSObject>
@property (nonatomic) BOOL didDisplayRecommendation;
@end

我知道如果我这样做我会得到一个无限循环:

- (void)setDidDisplayRecommendation:(BOOL)didDisplayRecommendation
{
    self.didDisplayRecommendation = didDisplayRecommendation;
}

但是当我尝试这个时,我得到一个编译器错误:

- (void)setDidDisplayRecommendation:(BOOL)didDisplayRecommendation
{
    _didDisplayRecommendation = didDisplayRecommendation;
}

请注意,didDisplayRecommendation 是协议中的属性。解决这个问题的最佳方法是什么?提前致谢!

【问题讨论】:

  • 不是重复的,没有解决符合协议的问题
  • 您可以在具有 (at)property (nonatomic,retain) MyClass *anObject 的类别中添加“特殊”属性 - 但在实现文件中,您所能做的就是 (at)dynamic anObject,然后,您可以使用关联引用函数来伪装其他对象来代替该属性。它有效,但不是解决方法,您可以在商业应用程序中执行此操作,并且它通过了实现协议检查。

标签: ios objective-c properties protocols objective-c-category


【解决方案1】:

不允许通过类别给类添加实例变量,见https://stackoverflow.com/a/13000930/171933

由于您需要一个变量来保存 didDisplayRecommendation 的值,因此您对类别执行此操作很不走运(除非您想弄脏 https://developer.apple.com/library/mac/documentation/Cocoa/Reference/ObjCRuntimeRef/Reference/reference.html#//apple_ref/doc/uid/TP40001418-CH3g-SW5)。

我建议重新考虑您的架构,看看您是否真的需要使用类别。子类甚至Mixins 可能是更好的选择。

【讨论】:

  • 您可以在具有 (at)property (nonatomic,retain) MyClass *anObject 的类别中添加“特殊”属性 - 但在实现文件中,您所能做的就是 (at)dynamic anObject,然后,您可以使用关联引用函数来伪装其他对象来代替该属性。它有效,但不是解决方法,您可以在商业应用程序中执行此操作,并且它通过了实现协议检查。
  • @unmircea 是的,这绝对是技术上可行的。但是,我认为您应该有一个非常令人信服的理由来诉诸关联引用。
【解决方案2】:

当您在协议中添加属性时,您需要@synthesize 它们。

【讨论】:

    【解决方案3】:

    我有一个宏可以让你在这样的类别中声明“属性”:

    @implementation NSObject (AwesomeUtils)
    
    JESynthesize(assign, NSInteger, index, setIndex);
    JESynthesize(strong, NSString *, name, setName);
    JESynthesize(copy, void(^)(void), completion, setCompletion);
    JESynthesize(unsafe_unretained, id, unsafeObject, setUnsafeObject);
    JESynthesize(weak, id<UITableViewDelegate>, delegate, setDelegate);
    JESynthesize(strong, NSString *, readonlyID, changeReadonlyID);
    
    // …
    @end
    

    我用引号说“属性”,因为即使没有 @property 声明,您也可以使用它们。该宏还可以支持weak。

    你可以在这里查看实现(头文件在底部): http://nspicks.com/2013/12/15/cleaner-properties-implementation-in-categories/

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多