objective-c - 为什么 iPhone 示例代码使用了这么多中间变量?

标签 objective-c ios memory-management simplification

我目前正在研究 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 的语义是什么(retaincopyassign),该语句都是错误的。我已经解释了最有可能的情况:保留。让我们看看其他两种可能性(完全不考虑它们是否有意义):

  • 如果 blueViewController 碰巧是一个 copy 属性,语句也会泄漏。属性访问器复制原始对象,现在该属性持有指向副本的指针,您丢失了对原始对象的跟踪,立即泄漏了它。

  • 最不可能的情况是 blueViewController 是一个 assign 属性,因为这很可能是错误的,而您确实想要 retain。但是,无论如何,assign 属性是针对您不拥有的对象,例如代表,你不应该释放他们。您正在将一个您拥有的对象分配给它,因此您要么泄露了它,要么错误地释放了分配属性。

关于objective-c - 为什么 iPhone 示例代码使用了这么多中间变量?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7042415/

相关文章:

ios - 不推荐使用 Objective-C 选择器的字符串文字,改用 '#selector'

iphone - 从plist创建NSArray

python - 比较 ruby​​ 和 python 代码之间的性能

memory-management - Appcelerator Titanium View 代理内存管理

ios - 使您的自定义 View Controller 成为根 IOS

iphone - 如何在 Facebook 或 Twitter 上发布带有本地镜像的格式化文本?

ios - Swift UI 是否像 UIKit 一样具有类似于 viewDidLoad() 的功能?如果没有,如何创建这样一个在启动时调用的函数?

ios - 为什么 UIImageView 不填满整个 CollectionViewCell 即使我有所有的约束

ios - 如何在 Swift 中以编程方式更改 UICollectionViewCell 大小?

memory-management - 有关N路集合关联缓存步骤的信息