Fat*_*tie 11 iphone cocoa-touch memory-management interface-builder nib
我发现这个问题的文档不清楚:
假设你正在使用iOS(不是Mac的情况,不需要提及差异).说严格是4.0+(不需要提及旧操作系统的差异).假设我们严格自动加载NIB.
假设你有一个UIViewController,BigView.假设NIB文件中有十几个所谓的"顶级"项目......可以是自定义控件,图像或其他任何内容.
假设您肯定会在应用程序运行期间多次明确创建然后摆脱BigView.所以:
对于NIB中的其中一个顶级项目,有三种可能性:
(1)根本没有任何形式的IBOutlet.
(2)你有一个连接的IBOutlet - 但不是属性.
(3)你确实有一个连接的IBOutlet属性(为了避免混淆,我们会说保留属性).
那么BigView发布时项目会发生什么?
在(3)的情况下,您必须明确释放.如果你不这样做,它将在视图消失后徘徊.没问题.
在(1)的情况下,我假设(但是任何人都可以确认?)当BigView消失时该项目将被释放.
在(2)的情况下,不清楚会发生什么.......
看看众所周知的参考链接:http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/LoadingResources/CocoaNibs/CocoaNibs.html这是非常可疑的:
"在iOS中,nib加载代码使用setValue:forKey:方法重新连接每个插座.该方法类似地寻找一个合适的访问器方法和[所以如果没有一个发生的话会发生什么?告诉我们APPLE ...]当失败时,它会回到其他方式...... [GOOD GRIEF!]"
并查看此文档:http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/LoadingResources/CocoaNibs/CocoaNibs.html并向下滚动到"Nib对象保留"
所以......
"nib文件中的对象创建时保留计数为1,然后自动释放" Fantastic ..
可是等等!读几句话......
但是,...如果没有可用的setter方法,则使用可用的setter方法或默认保留对象
他们在说什么?
它们是否意味着如果没有可用的setter(ivar,但没有属性),它是AGAIN RETAINED(除了他们在前一条款中提到的"保留") - 或者,他们只是重复自己,即"默认保留对象"与他们之前刚刚讨论的"保留"相同("使用保留计数1创建然后自动释放").
为什么他们甚至会提到自动释放,如果不是这样的话?
确实 - 如果有人真正明确知道这个问题的答案...... 你怎么知道的?!?你问过DTS,还是通过测试,或者?我建议,关键文档(只是粘贴)是非常不清楚的.
再次 - 如果你有一个IBOutlet,但不是一个属性,连接到"顶级"对象.. 你有责任释放它吗?它保留了吗?在那种情况下?
就此而言....仅仅在情况(1)中,当BigView消失时,它会被释放吗?我当然会认为情况确实如此,但谁知道呢?
问题是如果你使用IBOutlet iVar会发生什么,而不是属性......
我愚蠢地从来没有想过这个/假设太多,有没有人有决定性的答案?干杯!!
为了记录,我做了一个测试项目.
事实上(令我惊讶的是)将IB元素连接到IBOutlet的单纯行为实际上显然增加了一个保留.
(我只能从伪劣的文件中假设,在那种情况下你特别得到:保留,自动释放,保留 - 导致一个保持平衡.)
所以,这就是答案.
我将发布演示项目.我也将任何读者引导到下面的Jonah的答案,它完美地解释了setValue的行为:forKey:干杯
Jon*_*nah 11
我不知道是什么导致了这么多混乱,我认为"Nib Object Retention"文档准确地解释了会发生什么.让我们分解一下,然后看看会发生什么:
创建nib文件中的对象,保留计数为1,然后自动释放.
ClassLoadedFromNib *loadedObject = [[[ClassLoadedFromNib alloc] initWithCoder:coder] autorelease];
Run Code Online (Sandbox Code Playgroud)
但是,在重建对象层次结构时,UIKit使用setValue:forKey:方法重新建立对象之间的连接,
[filesOwner setValue:loadedObject forKey:nameOfIBOutlet];
Run Code Online (Sandbox Code Playgroud)
如果没有可用的setter方法,则默认使用可用的setter方法或保留对象.
-setValue:forKey:iOS中的默认行为是粗略的
//lazy pseudocode
if ([self respondsToSelector:@selector(@"setKeyName:")]) {
[self setKeyName:value];
}
else {
object_setIvar(self, _keyName, [value retain]);
}
Run Code Online (Sandbox Code Playgroud)
有关更多详细信息,请参阅键值编程指南.除非你的文件的所有者对象覆盖-setValue:forKey:(或+accessInstanceVariablesDirectly和-setValue:forUndefinedKey:)期望对象所有权进行如上管理.
如果为nib-file对象定义出口,则应始终定义用于访问该出口的setter方法(或声明的属性).出口的setter方法应保留其值,并且包含顶级对象的出口的setter方法必须保留其值以防止它们被释放.
允许nib加载将ivar直接设置到外部保留的对象是令人困惑的.不要那样做.为您的商店提供setter方法,以便明确加载对象的所有权.
如果未将顶级对象存储在出口中,则必须保留loadNibNamed:owner:options:方法返回的数组或数组内的对象,以防止这些对象过早释放.
未连接到插座的对象已自动释放.保留它们或从-loadNibNamed返回的数组:owner:options:如果您打算稍后尝试访问它们.
| 归档时间: |
|
| 查看次数: |
1453 次 |
| 最近记录: |