Apple示例代码上的代码错误?

时间:2011-03-18 23:17:09

标签: ios memory-management

我查看了Apple“PageControl”示例项目(See here),我在代码中看到了这个函数:

- (void)loadScrollViewWithPage:(int)page
{
    if (page < 0)
        return;
    if (page >= kNumberOfPages)
        return;

    // replace the placeholder if necessary
    MyViewController *controller = [viewControllers objectAtIndex:page];
    if ((NSNull *)controller == [NSNull null])
    {
        controller = [[MyViewController alloc] initWithPageNumber:page];
        [viewControllers replaceObjectAtIndex:page withObject:controller];
        [controller release];
    }

    // add the controller's view to the scroll view
    if (controller.view.superview == nil)
    {
        CGRect frame = scrollView.frame;
        frame.origin.x = frame.size.width * page;
        frame.origin.y = 0;
        controller.view.frame = frame;
        [scrollView addSubview:controller.view];

        NSDictionary *numberItem = [self.contentList objectAtIndex:page];
        controller.numberImage.image = [UIImage imageNamed:[numberItem valueForKey:ImageKey]];
        controller.numberTitle.text = [numberItem valueForKey:NameKey];
    }
}

有些事我不明白 如果测试部分if ((NSNull *)controller == [NSNull null])为真,那么我们有

controller = [[MyViewController alloc] initWithPageNumber:page];
[viewControllers replaceObjectAtIndex:page withObject:controller];
[controller release];

然后就在:

if (controller.view.superview == nil)

但是,控制器刚刚发布。我认为它可能有效,因为控制器仍然在内存中,但这不是编码这些东西的错误方法吗?

2 个答案:

答案 0 :(得分:3)

我认为你是对的。如果我正在编码,我会添加:

if ((NSNull *)controller == [NSNull null])
{
    controller = [[MyViewController alloc] initWithPageNumber:page];
    [viewControllers replaceObjectAtIndex:page withObject:controller];
    [controller release];
    controller = [viewControllers objectAtIndex:page];
}

释放后获取参考。

或者我认为另一种方法是使用autorelease而不是release。

答案 1 :(得分:2)

controller对象添加到保留对象的viewControllers中。因此,它们在发布之后仍然是一个活的对象。

是不是错了?也许,它需要了解NSArray的作用,但这很常见。

我会这样做的:

if ((NSNull *)controller == [NSNull null])
{
    controller = [[[MyViewController alloc] initWithPageNumber:page] autorelease];
    [viewControllers replaceObjectAtIndex:page withObject:controller];
    controller = [viewControllers objectAtIndex:page];
}