我知道HIG(这非常方便!),但是在编写Objective-C时,更具体地说,在使用Cocoa(或CocoaTouch)时,您使用了什么编程实践?


当前回答

避免生成

Since you typically(1) don't have direct control over their lifetime, autoreleased objects can persist for a comparatively long time and unnecessarily increase the memory footprint of your application. Whilst on the desktop this may be of little consequence, on more constrained platforms this can be a significant issue. On all platforms, therefore, and especially on more constrained platforms, it is considered best practice to avoid using methods that would lead to autoreleased objects and instead you are encouraged to use the alloc/init pattern.

因此,而不是:

aVariable = [AClass convenienceMethod];

在可能的情况下,你应该使用:

aVariable = [[AClass alloc] init];
// do things with aVariable
[aVariable release];

当您编写自己的方法返回新创建的对象时,您可以利用Cocoa的命名约定,通过在方法名前加上“new”来标记接收方必须释放该对象。

因此,与其:

- (MyClass *)convenienceMethod {
    MyClass *instance = [[[self alloc] init] autorelease];
    // configure instance
    return instance;
}

你可以这样写:

- (MyClass *)newInstance {
    MyClass *instance = [[self alloc] init];
    // configure instance
    return instance;
}

因为方法名以"new"开头,你的API的使用者知道他们负责释放接收到的对象(例如,看NSObjectController的newObject方法)。

你可以通过使用你自己的本地自动释放池来控制。有关这方面的更多信息,请参见自动释放池。

其他回答

打开所有GCC警告,然后关闭那些通常由Apple头文件引起的警告,以减少噪音。

还经常运行叮当静态分析;您可以通过“运行静态分析器”构建设置为所有构建启用它。

编写单元测试,并在每次构建时运行它们。

如果您使用的是Leopard (Mac OS X 10.5)或更高版本,则可以使用Instruments应用程序来查找和跟踪内存泄漏。在Xcode中构建程序后,选择使用性能工具> Leaks运行>。

即使你的应用程序没有显示任何泄漏,你可能把对象保存得太久了。在Instruments中,您可以为此使用ObjectAlloc工具。在Instruments文档中选择ObjectAlloc乐器,并通过选择View > detail(它旁边应该有一个复选标记)来显示乐器的详细信息(如果还没有显示的话)。在ObjectAlloc详细信息中的“分配生命周期”下,确保选择“已创建和仍然存在”旁边的单选按钮。

现在,每当您停止记录应用程序时,选择ObjectAlloc工具将在“# Net”列中显示对应用程序中每个仍然活动的对象的引用数。确保不仅要查看自己的类,还要查看NIB文件的顶级对象的类。例如,如果你在屏幕上没有窗口,而你看到一个仍然存在的NSWindow的引用,你可能没有在你的代码中释放它。

不要忘记NSWindowController和NSViewController会释放它们所控制的NIB文件的顶级对象。

如果手动加载NIB文件,则在使用完该NIB的顶级对象后,需要负责释放它们。

编写单元测试。您可以在Cocoa中测试许多在其他框架中可能比较困难的事情。例如,对于UI代码,您通常可以验证事物是否按照应有的方式连接,并相信它们在使用时能够正常工作。你可以很容易地设置状态和调用委托方法来测试它们。

在编写内部测试时,也不会有公共、受保护和私有方法可见性。

抵制世界的子类化。在Cocoa中,很多工作都是通过委托和使用底层运行时完成的,而在其他框架中则是通过子类化完成的。

例如,在Java中你经常使用匿名*Listener子类的实例,在. net中你经常使用EventArgs子类。在Cocoa中,你什么都不用做——而是使用目标-动作。