我面临一个奇怪的问题.. 我想在我当前的View中添加一个UIViewcontroller(称为iView)。 我是通过致电
来做到的 iView = [[KFKaraokeInfosView alloc] initWithKaraoke:karaoke NibName:@"InfosView" commingFromPlayer:NO];
iView.songTitle.text = karaoke.title;
[self.view addSubview:iView.view];
在iView的viewDidLoad中,我将其作为观察者添加到NotificationCenter以获取特定通知,例如
- (void)viewDidLoad
{
[super viewDidLoad];
self.title = @"About";
if ([karaoke.styles count] == 0)
{
[[NSNotificationCenter defaultCenter] postNotificationName:@"GetInfosOfSong" object:self.karaoke];
}
else
{
shouldSetup = YES;
}
[self.navigationController setNavigationBarHidden:NO animated:YES];
[self.navigationController.navigationBar setBarStyle:UIBarStyleBlack];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(setup) name:GetSongInfos object:nil];
[optionsTableView setBackgroundView:nil];
}
问题是当我在初始化时在iView上调用autorelease方法时,通知永远不会被捕获(因此从不调用setup方法),但是如果我不为iView调用autorelease,它就可以工作。
我不了解这种情况下的记忆管理,有人可以帮我理解吗?
答案 0 :(得分:0)
容器视图控制器方法可以在 UIViewController类参考的Implementing a Container View Controller中找到,示例代码可以在 View Controller编程指南的Creating Custom Container View Controllers中找到的
因此,在iOS 5及更高版本中,您可能应该:
iView = [[[KFKaraokeInfosView alloc] initWithKaraoke:karaoke NibName:@"InfosView" commingFromPlayer:NO] autorelease];
[self addChildViewController:iView];
iView.songTitle.text = karaoke.title;
[self.view addSubview:iView.view];
[iView didMoveToParentViewController:self];
如果这是iOS 4或更早版本,则不支持正确包含。您可以通过添加视图来手动对其进行kludge,而不是autorelease
:
iView = [[KFKaraokeInfosView alloc] initWithKaraoke:karaoke NibName:@"InfosView" commingFromPlayer:NO];
iView.songTitle.text = karaoke.title;
[self.view addSubview:iView.view];
您显然会在子视图控制器的某些ivar中保留子视图控制器的副本,而不是autorelease
它,而是在子视图被取消时显式release
子控制器。请注意,由于您在预收容iOS4世界中运行,因此您的子控制器无法保证接收各种事件(众所周知的旋转事件)。但是您应该收到通知中心的活动。
在iOS 4中尝试伪造遏制的这种丑陋的替代方法是根本不使用子视图控制器,而只是将子视图添加到父视图中。您实际上可以将其添加到父控制器的NIB,但只是隐藏它。然后,当你想要呈现它时,取消隐藏它。但是将所有内容保存在父视图控制器中并且它是NIB。我上面描述的方法,假装遏制,可能有用(我见过人们这样做),但它给了我heebie jeebies。这更简单。