在大多数例子我看到IBOutlets以下设置:
(Example A)
FooController.h:
@interface FooController : UIViewController {
UILabel *fooLabel;
}
@property (nonatomic, retain) IBOutlet UILabel *fooLabel;
@end
FooController.m:
@implementation FooController
@synthesize fooLabel;
@end
但是,这也工作正常(注意:没有财产,没有合成):
(Example B)
FooController.h:
@interface FooController : UIViewController {
IBOutlet UILabel *fooLabel;
}
@end
FooController.m:
@implementation FooController
@end
是否有限定IBOutlets如在实施例B中的任何缺点? 像内存泄漏? 似乎很好地工作,我宁愿不公开IBOutlets的公共属性,因为它们不被用作这样的,他们只在控制器实现使用。 定义它在三个地方没有真正的需要不打我非常DRY(不要重复自己)。
在Mac OS X,IBOutlets连接是这样的:
- 查找名为集方法<OutletName> :. 如果它存在调用它。
- 如果没有方法存在,寻找名为实例变量<OutletName>,设置它不保留 。
在iPhone OS,IBOutlets连接是这样的:
- 调用[对象的setValue:outletValue forKey:@ “<OutletName>”]
设定值的关键的行为是做这样的事情:
- 查找名为集方法<OutletName> :. 如果它存在调用它。
- 如果没有方法存在,寻找名为实例变量<OutletName>,将其设置并保留它。
如果你使用的属性,你会掉进:这两个平台上“ 寻找所谓一套方法<OutletName> ...”的情况。 如果只是用一个实例变量,那么你就会有不同的保留在Mac OS X VS iPhone OS /释放行为。 这没有什么错用一个实例变量,你只需要你的平台之间切换,以应对这种行为差异。
下面是完整的文档的链接只是这个话题。 https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/LoadingResources/CocoaNibs/CocoaNibs.html#//apple_ref/doc/uid/10000051i-CH4-SW6
在Mac OS X,IBOutlets不会被默认保留。 这是iPhone OS的行为相反:在iPhone OS上,如果不申报则保留了财产,你必须释放在该属性dealloc
方法。 此外,64位运行时可以使用合成属性声明实例变量。 这意味着,有一天实例变量(与IBOutlet
)可以被省略。
由于这些原因,更均匀,兼容总是创建一个属性,并使用IBOutlet
唯一的财产。 不幸的是,它也更详细。
在你的第一个例子中,你总是要释放出口中dealloc
方法。 在第二个例子中,你必须释放仅与iPhone OS出口。
最终的结果是完全一样的,但你必须保持一个几件事情:
其实这一切都归结到同旧的规则:“ 你要释放你分配/保留 ”。 所以,如果你使用一个实例字段作为出口,你没有分配/保留它,所以你不应该将其释放。
其可能的是这些实施例使用保留,因为样本代码被编程分配和初始化一个UILabel,然后将它添加到UIView的。 这对于许多例子的情况下,由于学习如何使用Interface Builder的往往不是他们的观点。
第二示例与IBOutlet中(没有属性和没有合成)用于当显影剂“分配”的界面生成器内的的UILabel(按钮,查看等) - 通过拖动IBOulet到标签或其他视图部件。 在我看来,前面的拖放操作(标签上查看)也添加子视图,标签到View - 等等。 标签由一个视图保留; 的视图被窗口保留; 窗口是由文件的所有者保留。 文件的所有者通常是您的文档,该文档在主启动了。
你会注意到,当你逐步执行程序(通过添加awakeFromNib
- (void)awakeFromNib
{
[fooLabel blahblah];
}
该fooLabel已经有一个内存地址。
那是因为标签是使用未初始化,但是从的initWithCoder文件包(笔尖文件)初始化。 基本上反序列化FILESTREAM一个对象 - 然后设置IBOutlet中的变量。 (我们还在谈论IBOutlet中的方法)。
还要注意的是,上述的iOS方法使用键值的方法
call [object setValue:outletValue forKey:@"<OutletName>"]
这是观测器/可观察图案。 该模式所需要的可观察对象引用在设置/阵列每个观察者。 值的变化将迭代设置/阵列,同样更新所有观察员。 这集将已经保持每个观察因而缺乏iOS中保留。
此外,剩下的就是投机。
看来情况下,当你使用Interface Builder然后
@property (nonatomic, retain) IBOutlet UILabel *fooLabel;
应尽可能改为
@property (nonatomic, weak) IBOutlet UILabel *fooLabel;
或@属性(非原子,分配)IBOutlet中的UILabel * fooLabel;
然后它不需要在dealloc方法被释放。 再加上它会满足OSX和iOS的要求。
这是基于逻辑,我可以在这里失去了一些作品。
然而,如果认为是通过你的节目的生命持续的可能并不重要。 而在一个模式对话框的标签(开,关,开,关)实际上可能有过保留,每个周期泄漏。 那是因为(再次炒)各封闭对话框序列化为一个文件系统,因此仍然存在X,Y位置和大小,与它的子视图等一起和反序列化之后...上开下一届会议(反对说minimiz或隐藏。)