IBOutlet
实例。一个例子就是UIButton
。所以他们在结构体中添加了这样一个东西: IBOutlet UIButton *whateverButton;
然后他们在.h文件中为每一个属性添加@property
,在.m文件中添加@synthesize
。
然后他们在.m文件的dealloc
中包含一个release
。两个问题:
- 释放是否必要?难道不是所有属性都已经自动处理了吗?
- 为了调试目的,如何检查引用计数以查看发生了什么情况?
IBOutlet
实例。一个例子就是UIButton
。所以他们在结构体中添加了这样一个东西: IBOutlet UIButton *whateverButton;
然后他们在.h文件中为每一个属性添加@property
,在.m文件中添加@synthesize
。
然后他们在.m文件的dealloc
中包含一个release
。两个问题:
发布是否必要?难道不是所有属性都已经自动处理了吗?
如果属性被保留,那么释放就是必要的。当您声明一个 @property
并且 @synthesize
它时,您得到的只是访问器,在 dealloc 中没有特殊的自动行为。
另外,IBOutlet 没有任何神奇之处 - 它只是 Interface Builder 用来查看您希望在 IB 中出现哪些属性的标记。它只是一个空的宏,单击 IBOutlet 关键字以查看其定义:
#ifndef IBOutlet
#define IBOutlet
#endif
void
。retainCount
也有所帮助。@synthesize
指令如何创建访问器。当您声明保留的@property
并要求编译器@synthesize
它们时,您会得到类似于以下内容:@property(retain) NSString *foo;
@synthesize foo;
- (void) foo {
return foo;
}
- (void) setFoo: (NSString*) newFoo {
// Try to think what would happen if this condition wasn’t
// here and somebody called [anObject setFoo:anObject.foo].
if (newFoo == foo)
return;
[foo release];
foo = [newFoo retain];
}
这不是完全相同的东西,但已经足够接近了。现在应该更清楚为什么你应该在dealloc中释放。
属性不会被"自动处理"。最接近的情况是,合成访问器会正确处理它们的内存管理职责。但这只是针对那些访问器而言。属性只是在类中声明可访问的"东西"的一种方式。除此之外,它们并没有得到太多特殊的处理。它不会开启某种垃圾回收机制。所以,是的,释放是必要的。
如果您想检查运行中的应用程序是否存在泄漏或未释放的内存,您应该使用像Instruments这样的调试工具。我不建议直接查看引用计数,因为它几乎是非常无用的——在任何时候都不能保证引用计数将是您所期望的,并且这并不一定表示问题。
您应该阅读苹果公司的Cocoa内存管理规则。一旦您掌握了这个规则,它就很简单了。我不一定建议先阅读其他指南,因为微妙的错误陈述可能会导致您走错方向(例如,属性将为您释放的想法可能来自于听到某人错误地陈述它们的工作原理)。
__weak
,它在非垃圾回收应用程序中没有任何影响。尽管弱引用通常是一个assign
属性的合理选择,这种情况下你不需要释放它(因为你没有保留它)。 - Chuck
retainCount
是不可靠的。(我自己没有尝试过。)这里有一个必要的链接:http://developer.apple.com/mac/library/documentation/cocoa/Conceptual/MemoryMgmt/Articles/mmRules.html#//apple_ref/doc/uid/20000994-BAJHFBGH - andyvn22