代表并保留周期?

时间:2012-08-13 15:27:08

标签: objective-c ios delegates

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

我在ivars声明了这些WhereamiViewController.h

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

作者写道,由于WhereamiViewController拥有locationManagerlocationManager's委托是WhereamiViewControllerlocationManager委托必须设置为nil in WhereamiViewController's dealloc方法因为委托是assigned而不是weak。在.xib文件worldViewlocationTitleField设置为委派File's Owner,但为什么这两个代表都不需要设置为nil它们也是assign而不是weak

PS:它正在使用ARC

3 个答案:

答案 0 :(得分:2)

  

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

CLLocationManager不会保留其委托。即使它确实将locationManager设置为nil dealloc也无法打破保留周期,因为保留周期会导致永远不会调用dealloc。需要一些其他事件来打破保留周期,例如解除/弹出视图控制器。

  

但为什么不将这两个设置为nil?

如果记录了该类没有保留该委托,那么您不必担心保留周期。有时,文档只是查看头文件并查找assign而不是strongretainCLLocationManager未保留其委托,因此您无需将locationManager分配给nil。但是,如果locationManager在您的课程被取消分配后仍可能收到事件,则应在nil方法中将其委托设置为dealloc,以防止在您的课程被取消分配后进行回调。

- (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
}

答案 1 :(得分:0)

  必须在WhereamiViewController的dealloc方法中将

locationManager设置为nil。

这没有做任何事情。

如果您使用手动引用计数,它应该在WhereamiViewController的dealloc中发布 (因为WhereamiViewController拥有它)。如果您具有包装locationManager实例变量的属性,则可以在dealloc中将该属性设置为nil以实现相同的效果,只要该属性是retain属性即可。但是,Apple通常不鼓励使用dealloc中的属性。

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

你应该在WhereamiViewController的dealloc中做什么,将位置管理器的委托设置为nil,因为如果位置管理器存在于dealloc之外,你不希望它将委托消息发送给不存在的WhereamiViewController。

同样,如果CLLocationManager的委托是一个弱引用,那么使用ARC,就会为你完成nilling。

  

但为什么不将这两个设置为nil?

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

答案 2 :(得分:0)

您需要将其设置为nil,仅作为预防措施。我混淆了你吗?让我解释一下。

nil的设置与retain release周期无关,只是为了避免locationManager向您的控制器发送委托调用。例如,如果locationManager在您的控制器被释放的同时更新位置,locationManager仍然将delegate引用设置为您的视图控制器,则会使用位置参数调用该委托。

但是由于您的控制器已被解除分配,因此该调用将导致内存访问不良。

但是,如果将其设置为nil,则不会抛出异常,因为nil指针的操作不会产生影响。