2

编辑:我真的很抱歉。我编辑了我在帖子中犯的令人困惑的错误。

我有这些ivars声明WhereamiViewController.h

CLLocationManager *locationManager;
IBOutlet MKMapView *worldView;
IBOutlet UITextField *locationTitleField;

作者写道,由于WhereamiViewController拥有locationManagerlocationManager's委托是WhereamiViewControllerlocationManager委托必须nilWhereamiViewController's dealloc方法中设置为,因为委托是assigned而不是weak。在.xib文件中worldViewlocationTitleField设置为委托,但是当这两个委托也都不是时File's Owner,为什么不需要将这两个委托设置为?nilassignweak

PS:它使用ARC

4

3 回答 3

2

locationManager must be set to nil in the WhereamiViewController's dealloc method

CLLocationManager不保留其代表。即使它确实设置locationManagernilindealloc也不会破坏保留周期,因为保留周期将导致dealloc永远不会被调用。需要有一些其他事件打破保留周期,例如关闭/弹出视图控制器。

但是为什么不需要将这两个设置为零?

如果 t 记录了该类不保留委托,那么您不必担心保留周期。有时文档来自仅查看头文件并寻找assign而不是strongor retainCLLocationManager不保留其委托,因此您不必分配locationManagernil. 但是,如果在您的类被解除分配后仍可能收到事件,您应该在方法locationManager中将其委托设置为以防止在您的类被解除分配后发生回调。nildealloc

- (void)dealloc
{
    //Prevent callbacks after dealloc
    //Useful if locationManager is a singleton or used elsewhere
    locationManager.delegate = nil;

    [locationManager release]; //If not ARC
    [super dealloc];//If not ARC
}
于 2012-08-13T15:38:38.420 回答
0

好吧,您需要将其设置为nil仅作为预防措施。我让你困惑了吗?让我解释。

to 的设置nil实际上与循环无关retain release,只是为了避免locationManager向您的控制器发送委托调用。例如,如果locationManager在您的控制器被释放的同时更新位置,locationManager仍然具有delegate对您的视图控制器设置的引用,将使用位置参数调用委托。

但是由于您的控制器已被释放,因此该调用将导致错误的内存访问。

但是,如果将其设置为nil,则不会引发异常,因为nil指针的操作没有任何影响。

于 2012-08-13T16:08:38.173 回答
0

locationManager在 WhereamiViewController 的 dealloc 方法中必须设置为 nil。

那没有任何作用。

如果你使用手动引用计数,它应该在 WhereamiViewController 的 dealloc 中释放(因为 WhereamiViewController 拥有它)。如果你有一个封装了 locationManager 实例变量的属性,你可以在 dealloc 中将该属性设置为 nil 来达到同样的效果,只要该属性是一个保留属性。但是,Apple 通常不鼓励在 dealloc 中使用属性。

如果您使用 ARC,编译器将为您完成所有这些工作。

您在 WhereamiViewController 的 dealloc 中应该做的是将位置管理器的委托设置为 nil,因为如果位置管理器在 dealloc 之后仍然存在,您不希望它向不存在的 WhereamiViewController 发送委托消息。

同样,如果 CLLocationManager 的委托是弱引用,则使用 ARC 会为您完成 nilling。

但是为什么不需要将这两个设置为零?

他们没有,但是当他们的代表被解除分配时,同样的推理也适用于他们的代表。

于 2012-08-13T15:42:04.430 回答