在UIScrollView中使用循环添加子视图会生成内存泄漏

时间:2012-01-09 18:40:19

标签: iphone objective-c ipad ios5 automatic-ref-counting

我是Objective-C的新手,我正在努力创建一个像应用程序一样的Springboard。所以我得到了一个UIScrollView,我在其中创建一个循环,从另一个UIViewController生成一堆子视图。

这是我的代码:

@implementation ProjectsListViewController {
    ProjectViewController *icon;
}

-

int row = 0;
int column = 0;
int page = 0;

for (int i = 0; i < 5; i++) {

    icon = [[ProjectViewController alloc] init];

    icon.iconPath = @"icon.png";
    icon.iconTag = i;

    int x = (1024 * page) + ((50 + (10 * column)) +  (188 * column));
    int y = (40 + (150 * row));

    icon.view.frame = CGRectMake(x, y, icon.view.frame.size.width, icon.view.frame.size.height);

    [self.scrollView addSubview:icon.view];

    // Add a new page if we reach the end of one
    if ((column == 4) && (row == 3)) {
        row = 0;
        column = 0;
        page++;

        // Add a new line if we reached last column
    } else if (column == 4) {
        column = 0;
        row++;

        // Add a column otherwise
    } else {
        column++;
    }
}

所有这些东西都在viewDidLoad方法中。直到那里如果我运行应用程序一切都很好,图标就在那里。 但是,当我想点击一个图标(按钮上有一个IBAction以推送到另一个视图)时,我的应用程序因可能的内存泄漏而崩溃。似乎再也没有对子视图的引用了。

我找到的唯一解决方案是在NSMutableArray中添加每个ProjectViewController。这样,我可以点击图标并推送另一个视图。

有人可以解释一下我做错了吗?

对不起,如果这听起来像是你的耳朵,我正在努力学习!

注意:我正在使用ARC。

4 个答案:

答案 0 :(得分:1)

如果没有任何东西引用循环外的图标类,它将被ARC收集。这就是为什么将它们添加到列表中可以解决问题。您是将图标的视图添加到列表中,以便最终引用它们。但没有什么能跟踪图标本身。

答案 1 :(得分:0)

如果他们被绑定到IBAction,你应该使用UIButton而不是图像。这样,您就可以保持代码模块化,并且不必担心管理两个不同对象和操作的内存。

另外,您应该查看此问题的最后一个答案: Why does static NSString leak?

答案 2 :(得分:0)

而不是:

icon = [[ProjectViewController alloc] init];

我愿意:

ProjectViewController *projectViewController = [[ProjectViewController alloc] init];

这样你每次都可以通过循环创建一个新的ProjectViewController实例,另一种方法是每次重新分配相同的UIViewController。

答案 3 :(得分:0)

Antoine你使用数组制作的解决方案,我会保持这样。

在没有阵列的情况下洞察出现问题 •图标是ProjectViewController(这是在动态创建并由ARC发布)
•将icon.view添加到任何视图将使其被所述视图保留 •触发图标的操作时,它会尝试向不再有效的ProjectViewController实例发送消息

使用你的数组(我假设它是一个属性(强)),添加到数组的每个ProjectViewController实例都不会被ARC释放,当你的图标动作被触发时,该方法被发送到一个有效的对象。