2

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

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

@property (nonatomic, retain) NSMutableArray* myArray;

为什么我这样做?

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

self.myArray = [NSMutableArray arrayWithCapacity:0];

后来在Dealloc...

self.myArray = nil;

还会发生什么

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

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

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

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

谢谢!

4

2 回答 2

5

只需使用类扩展的原则,该原则允许您将部分声明放在.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文件中的类扩展名中)将其重新声明为读写。

有关详细信息,请参阅Apple 文档


注意:

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

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

我的类.h

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

我的班级.m

@interface MyClass ()
    @property(nonatomic, retain) NSMutableArray *myArray;
@end


@implementation MyClass

[... MyClass implementation ..]

@synthesize myArray = _myArray;
@end

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

于 2012-10-08T09:48:09.207 回答