我是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。
答案 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释放,当你的图标动作被触发时,该方法被发送到一个有效的对象。