为什么在 viewDidUnload 中将 nil 赋给 IBOutlets?

2024-02-06

我有一个UIViewController有一个IBOutlet for a UILabel标签已连接到 XIB 中。

#import <Foundation/Foundation.h>

@interface MyViewController : UIViewController {
    IBOutlet UILabel *aLabel; 
}
@end

根据iOS 编程:大书呆子牧场指南(第二版) http://bignerdranch.com/book/ios_programming_the_big_nerd_ranch_guide_nd_edition_第7章

当 [MyViewController] 重新加载其视图时,将从 XIB 文件创建一个新的 UILabel 实例。

因此,它建议在viewDidUnload.

- (void)viewDidUnload {
   [super viewDidUnload];
   [aLabel release];
   aLabel = nil;
}

作为一名 C# 程序员,我一直被灌输这样的观念:为事物分配 nil/null 是毫无意义的。虽然我发现它在 Objective-C 中更有意义,但它仍然略微影响了我的代码审美感*。我将其删除,一切正常。

然而,当我尝试做类似的事情时MKMapView应用程序错误EXC_BAD_ACCESS尝试加载 NIB 时。

#import <Foundation/Foundation.h>

@interface MyViewController : UIViewController {
    IBOutlet MKMapView *mapView;
}
@end
- (void)viewDidUnload {
    [super viewDidUnload];
    [mapView release];
    mapView = nil; // Without this line an exception is thrown.
}

为什么会出现错误mapView未设置为nil,但不是当aLabel未设置为nil?

* 我意识到我需要调整我对新语言的代码审美感,但这需要时间。


事实证明我完全错了aLabel不被引用。不知道是什么让我认为不是。

然而,这仍然留下了一个问题:为什么在加载 NIB 时要引用它们。

当设置字段或属性时,将向旧值发送释放消息(合成属性设置方法发送释放消息,或者setValue:forKey:如果它是一个字段,则发送消息)。因为旧值已经被释放,所以结果是EXC_BAD_ACCESS.


这是因为内存管理,特别是缺乏垃圾收集。

在 C# 中(如您所知),不再在范围内的对象将被删除。在 Objective-C 中,这种情况不会发生。您必须依靠保留/释放来告诉对象您何时完成了它。

您的mapView bug 表现出了objective-c 引用计数方法的一个缺点。呼唤release对象上可能会导致它被释放。但是,指向该对象的指针仍将指向同一位置 - 您的对象将不再存在。

例如

// We create an object.
MyObject *object = [[MyObject alloc] init];

// At this point, `object` points to the memory location of a MyObject instance
// (the one we created earlier). We can output that if we want :
NSLog(@"0x%08X", (int)myObject);

// You should see a number appear in the console - that's the memory address that
// myObject points to.
// It should look something like 0x8f3e4f04

// What happens if we release myObject?
[myObject release];

// Now, myObject no longer exists - it's been deallocated and it's memory has been
// marked as free

// The myObject pointer doesn't know that it's gone - see :
NSLog(@"0x%08X", (int)myObject);

// This outputs the same number as before. However, if we call a method on myObject
// it will crash :
NSLog(@"%@", myObject);

在 Objective-C 中,如果你尝试调用消息nil, 什么都没发生。因此,如果每次您完成一个对象并对其调用release时,您还应该将其设置为nil- 这意味着如果您尝试再次使用该指针,它不会崩溃!

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为什么在 viewDidUnload 中将 nil 赋给 IBOutlets? 的相关文章

随机推荐