【问题标题】:Bad code on Apple sample code?Apple 示例代码上的错误代码?
【发布时间】:2011-07-18 12:59:01
【问题描述】:

我查看了 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)

但是,控制器刚刚发布。我认为它可能会起作用,因为控制器仍在内存中,但这不是一种错误的编码方式吗?

【问题讨论】:

    标签: ios memory-management


    【解决方案1】:

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

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

    释放后获取引用。

    或者我想另一种方法是使用自动释放而不是释放。

    【讨论】:

    • @fluchtpunkt :我不明白这个downvote的原因......这个答案似乎是有效的......
    【解决方案2】:

    controller 对象添加到保留该对象的viewControllers 时。因此,释放后它仍然是一个活体。

    错了吗?也许,它需要知道NSArray 做了什么,但这很常见。

    我会这样做的:

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

    【讨论】:

    • +1 对使用自动释放的想法。就目前而言,代码不仅依赖于 NSArray 保留添加到其中的对象这一事实(正如您所说,这很常见),而且还依赖于没有其他线程从 NSArray 中删除对象。 (诚​​然,由于这些是 UI 对象,这不太可能发生,但继续使用您不保留的对象仍然是不好的业力。)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-25
    • 2016-04-11
    • 2016-05-27
    • 1970-01-01
    相关资源
    最近更新 更多