【问题标题】:Can we have retain property with no getter and setters on Obj C elements?我们可以在 Obj C 元素中保留没有 getter 和 setter 的属性吗?
【发布时间】:2012-10-08 09:41:41
【问题描述】:

好的,所以我正在阅读一些关于 良好编程实践 的文章,我看到了一个声明,其中说为你的类公开你的所有元素并不是一个好主意。又名封装的概念

现在在 Objective C 中,当我为我的类创建一个元素时,我会执行以下操作,考虑一个 NSMutableArray

@property (nonatomic, retain) NSMutableArray* myArray;

我为什么要这样做?

以便将 Retain 属性赋予 myArray,从而赋予它更简单的内存管理周期。稍后,我将 viewDidLoad 中的 myArray 初始化为

self.myArray = [NSMutableArray arrayWithCapacity:0];

稍后在 Dealloc...

self.myArray = nil;

还会发生什么

通过提供这个属性并在 .m 文件中合成 myArray,我在不知不觉中为我的类的所有元素制作公共 Getter 和 Setter

此外,从 Xib 文件自动生成的 UI 元素确实应用了相同的声明。

继续为类的每个元素创建公共 Getter 和 setter 并不是一个好主意,对吧?

因此,绝对没有应用任何封装!如果我在这里错了,请纠正我并帮助我解决任何问题!

谢谢!

【问题讨论】:

  • 您可以在.m 文件中声明一个属性,使其从外部不可见。
  • @Stas :但是我该如何管理它的内存管理周期呢?我想为每个元素赋予属性是最好的方法!
  • @Stas:甚至苹果公司都建议只声明属性而忘记 ivars。只声明属性并且根本不声明 ivar(LLVM 将在必要时为您声明支持变量)要简单得多,因为那时一切(内存管理以及原子性和 KVO)都是自动管理的。 (在极少数情况下,出于优化目的,您可能更喜欢 ivars 而不是属性,但总的来说这是不值得的)
  • 不知道!非常感谢,将以您的回答为指导!

标签: iphone objective-c optimization encapsulation


【解决方案1】:

只需使用Class Extensions 的原则,它允许您将部分声明放入您的.m 文件中,从而使其在您的标题中不可见,而对其他类不可见。

(顺便说一下,这是 Apple 推荐的声明私有方法和属性的方式)

YourClass.h

@interface MyClass : MySuperclass
// public properties
// public methods
@end

YourClass.m

@interface MyClass()
// This is a class extension
// put here private properties
// and private methods too
@end

@implementation MyClass
// And your implementation of course here
@end

例如,您甚至可以在公共接口(在头文件中)中将属性声明为只读,然后在私有接口(在.m 文件的类扩展中)将其重新声明为可读写。

更多详情请参阅the Apple documentation


请注意:

  • 如果您声明属性,则无需声明实例变量:编译器会自动为您生成它,因此您不必费心并在.h 中声明它。在最新版本的编译器(现代 Objective-C)中,甚至不需要 @synthesize 指令,因为它现在会在不存在时自动生成(参见文档)
  • 如果您更喜欢声明实例变量,您也可以在 .m 的类扩展中执行此操作,方法与您在 .h 中执行的方式相同。这也是一种从公共标头中隐藏实例变量的方法。一般来说,我真的很少使用实例变量(因为只声明属性就足够了),如果我真的需要一个 ivar,我会在类扩展中声明它,使其在公共标头中不可见。

【讨论】:

    【解决方案2】:

    您可以在 class.m 文件中声明该属性,因此 getter 和 setter 方法只能在该类中访问。一个例子:

    MyClass.h

    @interface MyClass : NSObject {
        NSMutableArray *_myArray;
    }
    @end
    

    MyClass.m

    @interface MyClass ()
        @property(nonatomic, retain) NSMutableArray *myArray;
    @end
    
    
    @implementation MyClass
    
    [... MyClass implementation ..]
    
    @synthesize myArray = _myArray;
    @end
    

    所以你只能在“MyClass.h”文件中使用“self.myArray”。

    【讨论】:

    • 谢谢!得到了解决方案... :)
    • 请注意,如果您声明属性,则无需在 .h 中声明 ivar。如果它不存在,编译器将为您生成与您的属性关联的支持实例变量。 (如果你真的需要/想要声明除了属性之外的实例变量,你也可以在 .m 文件的类扩展中这样做,无论如何都要从公共头文件中隐藏它)
    • 好的,谢谢。写答案我使用我的默认声明,但用户也可以遵循你的建议:)
    猜你喜欢
    • 2023-03-30
    • 1970-01-01
    • 2017-04-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多