【问题标题】:public objects and use of property公共物品和财产的使用
【发布时间】:2011-09-26 20:37:34
【问题描述】:

我有点困惑;如果在 .h 文件中声明了一个对象,它会自动被视为“公共”,对吗?但是,我们在 .h 文件中使用 @property 来编辑它们?这是我不明白的地方:我们对私有对象使用 getter/setter,那么为什么我们对 .h 文件中声明的对象使用 @property 并因此被视为“公共”?

第二件事,我找到了这个例子:我不明白为什么我们在这段代码中使用@synthesize 代替primaryKey:http://staging.icodeblog.com/wp-content/uploads/2008/08/9-todom1.png 为什么我们不对database 对象使用@property?

【问题讨论】:

    标签: objective-c cocoa properties instance-variables


    【解决方案1】:

    如果在 .h 文件中声明了一个对象 (ivar),那么它是公共的,这是不正确的。只有提供了 getter/setter 方法,否则不提供。

    确实,@property/@synthesize 指令是用于声明和定义默认 getter/setter 方法的工具。因此,您只需使用指令,而不是自己编写它们。

    还值得注意的是,声明属性可以使用点符号来引用对象的属性。而且他们澄清了很多,感谢retain/assign/copy 说明符,如何为这些属性管理内存。 (当然,@synthesize 会为您正确地做到这一点。

    实际上,关于您的样本,ivar 是否与属性相关联是一种设计选择。可能,您只需重新考虑默认情况下在 .h 文件中声明的 ivars 是公共的假设,它会变得更加清晰。换句话说:primaryKey 是公开的,database 不是。

    一个很好的教程可以找到here,但也不要忘记Apple docs。

    编辑:

    关于您在评论部分提出的问题:

    不必每个 ivar 都有一个属性,也不必具有 getter/setter 才能在该类实现中使用。

    @interface SomeClass : NSObject {
        AnotherClass* _anotherClassObj;
        AThirdClass* _aThirdClassObj;
    }
    @property (nonatomic, retain) AnotherClass* anotherClassObj;
    @end
    

    所以,这里有两个 ivars;只有一个有@property 声明。在您的 .m 文件中,您可能有,例如

    @implementation SomeClass;
    @synthesize anotherClassObj = _anotherClassObj;
    
    - (void)initWithClasses:(AnotherClass*)obj1 and:(AThirdClass*)obj2 {
       .....
       self.anotherClassObj = obj1;
       _aThirdClassObj = obj2;
       ...
    }
    
    ....
    @end
    

    在这段代码中:

    1. @synthesize 将为anotherClassObj 提供getter/setter 实现,因此您可以使用语法:self.anotherClassObj = obj1;该语法可以在类实现的内部和外部平等地使用;

    2. 当您没有 getter/setter(自动生成或自定义)时,您可以使用语法 _aThirdClassObj = obj2; 直接分配给 ivar,语义与简单指针复制;无论如何,_aThirdClassObj 将无法从该类外部访问;

    3. 此外,尽管有@property ... anotherClassObj,您仍然可以直接在您的.m 文件中引用_anotherClassObj,就像在_anotherClassObj = xxx 中一样,如果您需要的话,可以绕过getter/setter。

      李>

    您应该清楚的一点是,getter/setter 不仅是使 ivar“公开”的一种方式。它们在管理保留计数方面也发挥着重要作用(取决于您在属性声明中的保留/分配/复制中选择的说明符)。因此,在上面的self.anotherClassObj = obj1; 中,obj1 被分配给_anotherClassObj 并且它也被保留(如果_anotherClassObj 之前指向一个对象,那么该对象将被发送一个release)。原始 ivar 分配不提供那种设施。

    在我看来,属性的保留计数管理功能在决定我是否使用属性方面远比可见性重要。

    【讨论】:

    • 感谢 sergio,所以 .h 文件中的每个 ivar 都必须有一个属性,如果我们想在 .m 文件中使用它并在它后面加上一个“=”符号(这意味着我们会使用二传手)?或者我们可以在 ivars 不获取属性和合成事物的代码中找到?
    • @Paul #2。尝试阅读this。
    • @sergio :感谢 sergio 的编辑!好的,所以这是针对像 AnotherClass* _anotherClassObj 这样的“对象”,但我们永远不会看到整数或任何其他原语的“属性”?而且,除了保留的东西,看到一个不使用“属性”的对象是否很常见?再次感谢
    • @Paul:您当然可以拥有原始类型的属性。它们默认具有复制语义,您无需指定它是否为保留/分配/复制。至于它是否常见,您通常可以做任何对您的应用有意义的事情,但我认为属性对于可读性(更不用说正确性)非常有用,以至于很难不想使用它们。另一方面,如果我发现一个根本不使用属性的类,我会认为它没有问题。
    【解决方案2】:

    并非标题中的所有内容都是公开的,默认情况下 ivars({ } 中的项目)是@protected。 @property 的目的是数据封装。 @synthesize 或 @dynamic 用于声明您希望实现属性的方式,其中一种是防止崩溃和警告所必需的。

    资源:
    Defining Classes       @protected、@package、@private、@public 参考
    Declared Properties  @property 参考

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-12-17
      • 1970-01-01
      • 2019-08-28
      • 2011-03-13
      • 1970-01-01
      • 2018-05-18
      • 2011-12-21
      • 2016-02-13
      相关资源
      最近更新 更多