2

我正在写一个iPhone应用程序。从导航堆栈[称为EditCreatorController]中的视图控制器开始,我将呈现一个定制的模式视图控制器[称为BMSStringPickerController]。我已经创建了一个委托协议等,按照Apple的指导原则将数据传递回第一个视图并使用该视图来消除模态视图。我甚至可以从模态控制器获得预期的数据,并能够很好地解决它。问题是,在这一点上,几乎我取原视图控制器上执行任何操作导致调试器的错误等解散模态视图后,父视图似乎解除分配?

- [EditCreatorController performSelector:withObject:withObject:]:消息发送到释放的实例0x3a647f0

- [EditCreatorController的tableView:willSelectRowAtIndexPath:]:发送到释放的实例0x3c12c40

换句话说消息时,它看起来像原始视图控制器已蒸发,而模态的视图被示出。无论这两个委托回调中哪一个被调用,都是如此。

下面是从调用模式视图父控制器代码:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { 
if (indexPath.row == 1) { // selection on creator type row 

    // create a string picker to choose new creator type from list 
    BMSStringPickerController *picker = [[BMSStringPickerController alloc] initWithNibName:@"BMSStringPickerController" bundle:nil]; 
    picker.delegate = self; 
    picker.stringChoices = [NSArray arrayWithObjects:@"composer", @"lyricist", @"arranger", @"original artist", @"other", nil]; 
    picker.currentChoice = creator.type; 
    picker.title = @"Creator Type"; 

    // wrap it in a nav controller so we can get tile bar etc. (from VC prog guide p. 93) 
    UINavigationController *newNavigationController = [[UINavigationController alloc] 
                initWithRootViewController:picker]; 

    [self.navigationController presentModalViewController:newNavigationController animated:YES]; 
    [newNavigationController release]; 
    [picker release]; 

} 
} 

,这里是委托回调:

- (void)stringPickerController:(BMSStringPickerController *)picker didPickString:(NSString *)string { 
NSLog(@"received string back: %@", string); 
typeLabel.text = string; // only change the label for now; object only changes if done button pressed 
[self.tableView reloadData]; 
[self dismissModalViewControllerAnimated:YES]; 
} 

- (void)stringPickerControllerDidCancel:(BMSStringPickerController *)picker { 
NSLog(@"picker cancelled"); 
[self dismissModalViewControllerAnimated:YES]; 
} 

另一个奇怪的事情(也许是一个线索)是,虽然我收到“收到的字符串”NSLog消息,并将其分配给typeLabel.text(typeLabel是IBOutlet到我的表视图中的一个标签),它永远不会出现在那里,即使使用表重新加载。

任何人有一些想法?

回答

2

也许你会发布delegatedeallocBMSStringPickerController

+0

宾果!谢谢迈克尔。一旦你指出,那么血腥显而易见! 这确实提出了一个问题:如果我不在那里发布它,现在是否有内存泄漏?看起来我的原始调用视图(代表)现在有一个额外的保留。或者可能不是 - 在选取器对象中的声明是: @property(assign)id delegate; 因此,因为它的分配不保留,我想当选择器通过电话dismissModal消失...一切再清洁记忆明智? (显然,我仍然在加深对obj-c内存管理的理解!):-) – 2010-07-12 23:06:20

+0

你是对的 - 一旦属性没有标记为“保留”或“复制”,它就不会被保留,也不需要释放它。你最好把它设置为零... – 2010-07-12 23:22:54

1

它可能不会解决你的问题,但我建议告诉拾取解雇本身(委托方法),允许响应链正确处理解雇:

[picker dismissModalViewControllerAnimated:YES]; 
1

的默认行为时有内存警告是释放所有不可见的视图控制器的视图。因此,如果在模态视图控制器中存在内存警告,则其父视图控制器可能会卸载其视图。

发生这种情况时,在视图控制器上调用viewDidUnload,以便您可以释放视图中的任何引用。如果你有引用,你没有保留,它们将在视图被卸载时失效。也许这发生在你的情况?

有关详细信息,请参阅UIViewController reference Memory Management部分。如果视图当前不可见,则UIViewController方法didReceiveMemoryWarning:释放视图,然后调用viewDidUnload。