UIViewController析构函数未被调用

时间:2015-04-25 20:27:49

标签: ios objective-c uiviewcontroller

目前我有两个名为FormAFormB

的UIViewControllers

现在FormA调用FormB,因此(formA中的formB属性是非原子且强大的)

self.formB = [[ MediaPlayer alloc] initWithNibName:@"MediaPlayer" bundle:nil ];
//Pass some values to FormB (all of these fields are strong)
((formB*)self.formB).SongInProgress_Name= songName;
((formB*)self.formB).SongInProgress_Path= song_path;
((formB*)self.formB).MusicCollectionPath= self.ArraySongNamePath;
[self presentViewController:self.formB animated:TRUE completion:nil];

当FormB尝试关闭时,它会返回到FormA

[ ((FormA*)self.presentingViewController) BackHere];

现在回到FormA。 FormA尝试以这种方式关闭FormB

[self.presentedViewController dismissViewControllerAnimated:TRUE completion:nil];

self.formB = nil;

执行上述操作不会调用FormB中的析构函数

-(void)dealloc {

    /* Desructor*/
}

为什么没有调用析构函数?

2 个答案:

答案 0 :(得分:4)

这可能不是问题的根源,但你应该从不这样做:

self.formB = [[ MediaPlayer alloc] initWithNibName:@"MediaPlayer" bundle:nil ];

保留对要呈现的视图控制器的强引用不是您的事。视图层次结构将保留它。你不是主人;视图层次结构是。所以你不能取得所有权。在创建和显示视图控制器时,将其设为 local 变量:

MediaPlayer* mp = [[ MediaPlayer alloc] initWithNibName:@"MediaPlayer" bundle:nil ];
mp.SongInProgress_Name = songName; // etc.
[self presentViewController:mp animated:TRUE completion:nil];

现在,正如我在开始时所说,这很重要,但可能不是问题的根源。您可能在MediaPlayer的实现中有保留周期。但是你没有显示任何代码,所以我无法知道。为什么不使用Instruments和Leaks模板找出保留周期的位置?

答案 1 :(得分:1)

Matt的答案补充说,由于保留周期,您的视图控制器很可能不会解除分配。这些是由彼此保持强引用的对象生成的,这在您没有正确地解耦视图控制器时很常见,例如:

您可以将行[((FormA*)self.presentingViewController) BackHere];更改为[self.presentingViewController dismissViewControllerAnimated:YES completion:nil]来优化代码。这使得FormB成为一个更抽象的视图控制器,可以在将来从其他不是FormA的视图控制器中呈现,并且不再需要将FormB存储为FormA中的变量,从而增加了两个类的解耦并减少了你无意中创造一个保留周期的可能性。