【问题标题】:Will declaring a property in an ObjC category override a property of the same name that's declared on the public interface?在 ObjC 类别中声明属性会覆盖在公共接口上声明的同名属性吗?
【发布时间】:2019-02-05 23:15:54
【问题描述】:

这不是为了解决任何特定问题,只是想了解 Objc 中属性的细微差别。

说我有课Dude

# Dude.h

@interface Dude: NSObject

@property (readonly, nonatomic) NSNumber *height;

@end

我在实现文件中扩展了类,但是改变了属性。

# Dude.m

@interface Dude()

@property (readwrite, atomic) NSNumber *height;

@end


@implementation Dude
@end

我得到一个错误。

属性“height”上的“atomic”属性与属性不匹配 继承自“老兄”

那么这里实际发生了什么。扩展上的属性是否相同?我只是覆盖了访问器吗?

此外,当我更改顺序以使公共接口为 readwrite 但私有接口为 readonly 时,我收到错误:

在类扩展“Dude”中非法重新声明属性(属性 必须是'readwrite',而它的主要必须是'readonly')

这让我觉得这是一个完整的重新声明,但现在我不太确定实际发生了什么。寻求澄清。

【问题讨论】:

    标签: objective-c


    【解决方案1】:

    在 Apple 的 The Objective-C Programming Language 中,他们将“扩展”描述如下,并以属性的重新声明为例:

    扩展

    类扩展类似于匿名类别,只是它们声明的方法必须在相应类的主@implementation 块中实现。使用 Clang/LLVM 2.0 编译器,您还可以在类扩展中声明属性和实例变量。

    类扩展的一个常见用途是将公开声明为只读的属性重新声明为私有的 readwrite:

    @interface MyClass : NSObject
    @property (retain, readonly) float value;
    @end
    
    // Private extension, typically hidden in the main implementation file.
    @interface MyClass ()
    @property (retain, readwrite) float value;
    @end
    

    ...

    因此,如此处所示,此模式是“重新声明”属性。不过,这是同一个属性。仅当您希望编译器合成私有 setter 时才重新声明属性,即使公共接口声明为 readonly。如果不在扩展中将属性重新声明为readwrite,则根本不会合成setter。

    您的各种警告实际上说明了我们正在处理相同属性的事实,因为只是您的重新声明的性质与公共接口中包含的内容不兼容的示例。

    【讨论】:

      【解决方案2】:

      你可以把它想象成一个公共和私有的接口。

      .h 文件中声明的接口是您的类的公共接口。 因此,如果您有理由将属性声明为 readonly,那么它是有意义的。

      .m 文件中的无名类别 (Dude()) 是您对属性的私人查看。因此,您可以在此处指定 readwrite 以使您的类能够在内部更改属性,但不能对外界进行更改。

      您还可以将这些声明用于您的方法,以在 .h 中声明公共接口,在 .m 中的接口 Dude() 中声明私有方法。

      您的公共和私有接口中的组合必须有意义,您不能声明公共属性 readwrite 并在内部说它只是只读...

      最后是 Objective-C:它只适用于你的编辑器和编译器。任何存在的东西都可以被访问,即使它被声明为某种私有的。

      【讨论】:

      • @JoeSusnick 这在您正在使用的模式上是正确的。更清楚一点:当您触发错误时,这是​​因为您的私有声明与公共声明不兼容。 Tom 公开readonly 和私下readwrite 的示例很常见并且效果很好。您最终得到的基础属性是相同的属性,具有不同级别的访问/可见性。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-06-07
      • 2011-10-11
      • 1970-01-01
      • 2012-09-05
      • 2015-12-29
      • 1970-01-01
      相关资源
      最近更新 更多