苹果示例代码存在糟糕的代码?

5
我已经查看了苹果的“PageControl”示例项目(请点击这里),并在代码中看到了以下函数:
- (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个回答

3

我认为你是正确的。如果我在编写这个程序,我会添加:

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

在释放后获取一个引用。

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


@fluchtpunkt:我不明白这个踩票的原因... 这个答案似乎是有效的... - Oliver

2

controller对象添加到viewControllers中后,会对这个对象进行保留。因此,在他们释放它之后,它仍然是一个活动对象。

这是否有错?也许需要了解NSArray的工作原理,但这是相当常见的。

我会这样做:

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

赞同使用自动释放池的想法。目前,代码不仅依赖于NSArray保留添加到其中的对象(正如您所说,这是相当普遍的),还依赖于没有其他线程从NSArray中删除对象。(尽管这些是UI对象,但这种情况不太可能发生,但继续使用未保留的对象仍然是不好的习惯。) - David Gelhar

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接