虽然编码始终存在与IBOutlets的保留计数相同的问题:在从NIB取消归档对象后保留计数?何时使用@ property's作为IBOutlet?设置时保留或分配? Mac和iPhone之间的差异?
所以我从Apple的文档中读到了The Nib Object Life Cycle。 Mac和iPhone上的一些测试应用程序给了我一些奇怪的结果。不过我写了一些规则如何处理这个问题,以便在编码时保持快乐,但现在想要与社区核实并倾听您的意见和经验:
附注:
所以问题是:这是正确和良好的做法吗?
我希望你能批准或纠正它。
答案 0 :(得分:10)
始终让你的笔尖'文件的所有者成为NSWindowController或NSViewController(在Mac OS X上)或UIViewController(在iPhone上)的子类,并使用@property (retain) IBOutlet
作为其所有出口,在控制器子类-dealloc
方法中执行适当的发布。
此模式适用于两者 Mac OS X 和 iPhone OS,因为Mac OS X上的NSWindowController和NSViewController会为您隐藏所有顶层对象(并在他们自己的-dealloc
方法中放弃它,并且在操作nib加载期间,iPhone OS不会为您提供任何隐含的顶级对象所有权。
答案 1 :(得分:1)
顶级对象:“没有拥有对象”
尼克斯。顶级对象归文件所有者所有,即文件所有者,因为它拥有文件中的所有顶级对象。
Windows有这个选项来释放自己是为了方便,但我发现我的设计更干净(即使它更多一些工作)当我关闭它并自己管理它的生命周期,就像我拥有的任何其他对象,或者使用窗口控制器。
如果您认为这与您引用的文档有冲突,那么让我们来看看整个段落:
nib文件中的对象最初是使用保留计数1创建的。但是,在重建对象层次结构时,AppKit会自动释放任何具有父对象或拥有对象的对象,例如嵌套在视图层次结构中的视图。
从而扼杀了自己的所有权。 nib加载器不想拥有你的对象。
在完成nib加载代码时,只有nib文件中的顶级对象具有正保留计数且没有拥有对象。您的代码负责释放这些顶级对象。
换句话说,它正在将所有权交给你。
奇怪的是,如果你的属性保留了语义,你实际上会泄漏对象。文档说你应该保留它:
对于Mac OS X和UIKit,管理nib文件中顶级对象的推荐方法是在File的Owner对象中为它们创建出口,然后定义setter方法以根据需要保留和释放这些对象。
但是如果你这样做,即使你释放了它的所有权,该对象仍将保持活着。
我想我会提出一个关于此问题的错误。 (编辑:完成.x-radar:// problem / 7559755)至少,nib加载器不应该切换两个保留,它在my test app(在10.5.8和10.6.1)。
答案 2 :(得分:1)
从上面提到的apple's doc:
对于Mac OS X和UIKit,管理nib文件中顶级对象的推荐方法是在File的Owner对象中为它们创建出口,然后定义setter方法以根据需要保留和释放这些对象。即使在应用程序使用垃圾收集的情况下,Setter方法也为您提供了包含内存管理代码的适当位置。实现setter方法的一种简单方法是创建声明的属性(使用@property语法)并让编译器为您创建它们。有关如何定义属性的更多信息,请参阅Objective-C编程语言。
否则使用@property(非原子,保留)IBOutlet * outletName;
答案 3 :(得分:0)
我可以写下我对iPhone NIB开发的看法:
希望它有所帮助...
答案 4 :(得分:0)
您应遵循标准内存管理准则。如果您的插座已连接到retain
ed属性,则必须在-dealloc
消息中将其释放。
是的,任何其他对象未保留的顶级对象通常都需要由您自己保留。
答案 5 :(得分:0)
1)一般来说,为什么你会有一个没有IBOutlet的顶级对象指向它呢?这个要求从来没有像现在这样严格限制。
2)我认为你有适合iPhone的设置。你也可以在iPhone上使用assign属性,这可以达到你所期望的......但是通常在经过大量使用后我更喜欢使用retain属性,因此当我考虑释放对象时,我100%清楚(特别是用viewDidUnload方法来实现)。
另外,作为旁注,调用[self.property release]是不好的形式。这使得引用保持原样但可能无效,如果其他东西也释放了对象...要么说self.property = nil,要么(更好)直接将基础类变量设置为nil而不使用dealloc语句中的属性(以避免任何dealloc可能产生的副作用。
正如我在回复另一张海报时所提到的,您可以使用在私有类本地类别扩展中声明的IBOutlet属性来保持清洁,因此它们不是公共属性。看起来像是:
// in .m file
@interface MyClass ()
@property (nonatomic, retain) IBOutlet UIView *myPrivateView;
@end
@implementation MyClass
@synthesize myPrivateView;
.....