我目前正在研究 Apress 的“开始 iPhone 3 开发”。他们在示例应用程序中使用的标准类似于以下代码:
- (void)viewDidLoad {
BlueViewController *blueController = [[BlueViewController alloc]
initWithNibName:@"BlueView" bundle:nil];
self.blueViewController = blueController;
[self.view insertSubview:blueController.view atIndex:0];
[blueController release];
}
8.14.11 更新(附加信息)
blueViewController 声明如下:
@property (retain, nonatomic) BlueViewController *blueViewController;
每当他们执行 alloc
时,他们都会将其放入某个临时变量(这里是 blueController
),然后分配它,然后释放它。这个临时变量对我来说似乎是多余的。
我将代码简化如下:
- (void)viewDidLoad {
self.blueViewController = [[BlueViewController alloc]
initWithNibName:@"BlueView" bundle:nil];
[self.view insertSubview:blueViewController.view atIndex:0];
}
- (void)dealloc {
[blueViewController release];
[super dealloc];
}
我修改后的代码在 iPhone 模拟器中运行完全一样。
现在,我知道如果你分配了一些东西你需要释放它的规则。我在我的 dealloc
方法中介绍了这一点。但是直接在 ViewDidLoad
(调用 alloc
的函数)中发布是否有一些优势?或者像这样在您的 dealloc
方法中有一个 release
是否同样可以?
感谢您的帮助,
-j
最佳答案
假设 blueViewController
是一个 retain
属性,临时变量不是多余的。您的简化会造成内存泄漏。来自第二个片段泄漏的声明:
self.blueViewController = [[BlueViewController alloc]
initWithNibName:@"BlueView" bundle:nil];
在所有权方面,您拥有 alloc-init 返回的对象,然后属性访问器再次声明该对象的所有权,导致该对象被过度保留。
使用临时变量解决了这个问题。另一种选择是使用 autorelease
:
self.blueViewController = [[[BlueViewController alloc]
initWithNibName:@"BlueView" bundle:nil] autorelease];
请注意,在这条语句之后,您实际上拥有该对象,并且您必须在 dealloc 中释放它。
您没有提到属性 blueViewController
是如何声明的。无论如何,无论 setter 的语义是什么(retain
、copy
、assign
),该语句都是错误的。我已经解释了最有可能的情况:保留
。让我们看看其他两种可能性(完全不考虑它们是否有意义):
如果
blueViewController
碰巧是一个copy
属性,语句也会泄漏。属性访问器复制原始对象,现在该属性持有指向副本的指针,您丢失了对原始对象的跟踪,立即泄漏了它。最不可能的情况是
blueViewController
是一个assign
属性,因为这很可能是错误的,而您确实想要retain
。但是,无论如何,assign
属性是针对您不拥有的对象,例如代表,你不应该释放他们。您正在将一个您拥有的对象分配给它,因此您要么泄露了它,要么错误地释放了分配属性。
关于objective-c - 为什么 iPhone 示例代码使用了这么多中间变量?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7042415/