【问题标题】:Since when is it possible to declare Objective-C 2.0 properties in a category?从什么时候开始可以在类别中声明 Objective-C 2.0 属性?
【发布时间】:2010-12-27 16:34:19
【问题描述】:

我一直认为不能在类别中声明对象属性。 直到我的伙伴在我们的应用程序代码中做到了这一点,并且它似乎有效。

我进行了 SO 和 Google 狂欢,试图向他解释不,Objective-C 类别只能用于添加方法,而不是属性。我发现了以下问题:

但后来我在 Apple 的网站上找到了 this link,其中包含以下关于 @property 声明的内容:

属性声明以 关键字@property。 @property 可以 出现在方法的任何地方 声明列表中找到 @interface 类。 @property 可以 也出现在声明中 协议或类别。 (强调)

我知道这行不通:

@interface MyClass ()
NSInteger foobar;
- (void) someCategorizedMethod;
@end

但这编译:

@interface MyClass ()
@property NSInteger foobar;
- (void) someCategorizedMethod;
@end

我的问题是 (a) 这里的最佳做法是什么? (b) 这对 Objective-C 2.0 来说是新事物吗?不是使用“真正的”iVar,而是简单地在幕后使用关联存储来完成这项工作?

【问题讨论】:

    标签: objective-c properties categories


    【解决方案1】:

    您始终可以在类别中声明@property。你不能做——而且仍然不能做——是在类别中声明属性的存储,既不是作为实例变量,也不是通过`@synthesize。

    但是....

    @interface MyClass ()不是一个类别。它是一个类扩展,具有明显比类别更具体的作用。

    也就是说,类扩展可用于扩展类的@interface,这包括可以@synthesized 的@properties(包括在现代运行时中合成存储)。

    Foo.h:
    
    @interface Foo
    @end
    
    Foo.m:
    
    @interface Foo()
    @property int x;
    @end
    
    @implementation Foo
    @synthesize x; // synthesizes methods & storage
    @end
    

    它只是使用关联存储 在幕后完成这项工作?

    不——它是一个真实的实例变量。现代运行时修复了脆弱的基类问题。


    @interface MyClass ()
    NSInteger foobar;
    - (void) someCategorizedMethod;
    @end
    

    上述方法不起作用(如预期的那样),因为foobar 实际上是一个全局变量。

    如果你把它改成:

    @interface MyClass () {
        NSInteger foobar;
    }
    - (void) someCategorizedMethod;
    @end
    

    然后它将与最新版本的 llvm 编译器一起工作(使用正确的标志,正如@Joshua 在评论中指出的那样)。

    【讨论】:

    • 此外,他添加 iVar 的第一个示例在带有 -Xclang -fobjc-nonfragile-abi2 的 llvm 中完全有效
    • 如果他添加了一个 ivar。在这种情况下,他正在添加一个不是实例变量的静态变量。
    • 感谢您的详尽解释。我将与我的编码伙伴分享此链接!
    【解决方案2】:

    一般来说,属性与其他方法没有什么不同。只要使用的ivar在普通类中可用,完全没有问题。这只是语法糖。

    如果 ivar 也被自动创建,事情就会变得更加困难,这在 一些 配置中是可能的。

    这里的重点是 ivar 的声明独立于属性。

    【讨论】:

      【解决方案3】:

      关联存储是解决方案。 看看这个post

      【讨论】:

      • 感谢您的跟进——这确实是解决此问题的一种可能方法。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-10-06
      • 1970-01-01
      • 2011-11-09
      • 2019-10-10
      • 2020-01-21
      • 1970-01-01
      相关资源
      最近更新 更多