未收到addSubview通知

时间:2013-01-02 15:24:56

标签: memory notifications autorelease ios4 addsubview

我面临一个奇怪的问题.. 我想在我当前的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,它就可以工作。

我不了解这种情况下的记忆管理,有人可以帮我理解吗?

1 个答案:

答案 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。这更简单。