objective c:for循环越来越慢

时间:2011-05-14 16:34:04

标签: iphone objective-c cocoa-touch ios loops

我对iPhone / iPad编程很陌生。我有for循环的问题,就像我在这个例子中使用的那样。该程序按预期工作。只有在每次调用函数之后(在这个例子中 - (void)writeLabels),它变得越来越慢。谁能告诉我为什么?在此示例中,需要50到100次点击才能发现延迟。但是,一旦我将更多指令打包到循环中,程序就变得太慢,因此只有在点击几下后才能使用。自动释放池也无济于事。

- (void) writeLabels {

label_y = 0;

for (i = 0; i < 23; i++) {
    UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(i * i, label_y, 39, 39)];
    label.textColor = [UIColor whiteColor];

    if (offset == i) {
        label.backgroundColor = [UIColor blackColor];
    }
    else label.backgroundColor = [UIColor blueColor];

    [label setText:[NSString stringWithFormat:@"%d", i]];
    [self.view addSubview:label];

    [label release];
    label_y += 40;
    }
}
- (IBAction) pushPlus {

++offset;
if (offset == 23) offset = 0;
[self writeLabels];

}

2 个答案:

答案 0 :(得分:6)

writeLabels方法中,您将标签添加为子视图。但你从未删除过以前的标签。所以在第一次通话后你有24个标签子视图,在第二次通话后你有48个,依此类推。每次调用时内存消耗都会增加,程序会变慢并最终崩溃,尽管此处没有内存泄漏。这不是泄漏,但你在内存中保留了不必要的东西。我想对于第二个,第三个,...调用以前的标签是没有必要的,毕竟你在每次调用中都在相同的位置创建它们。保持一种方法来跟踪添加的标签(可能是使用标签),然后在添加新标签之前从superview中删除以前的标签。

编辑:最好将标签作为Jonah建议的班级成员。像这样:

- (id)init {
    if (self = [super init]) {
        // labelsArray is a member of the class
        labelsArray = [[NSMutableArray alloc] initWithCapacity:24];
        NSInteger label_y = 0;

        for (NSInteger i = 0; i < 23; i++) {
            UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(i * i, label_y, 39, 39)];
            [labelsArray addObject:label];
            [label release];
            label_y += 40;
        }
    }
}

- (void)viewDidLoad {
    for (NSInteger i = 0; i < 23; i++) {
        UILabel *label = (UILabel *) [labelsArray objectAtIdex:i];
        [self.view addSubview:label];
        label.text = [NSString stringWithFormat:@"%d", i];
    }
}

- (void) dealloc {
    [labelsArray release];
}

- (void) writeLabels {
    for (NSInteger i = 0; i < 23; i++) {
        if (offset == i) {
            label.backgroundColor = [UIColor blackColor];
        } else {
            label.backgroundColor = [UIColor blueColor];
        }
}

答案 1 :(得分:4)

[self.view addSubview:label];

每次调用此方法时,都会在视图中添加其他子视图。您永远不会删除任何这些子视图,因此每次方法调用都会增加内存使用量。

不是每次构造一次都创建新标签。在控制器中保留对它们的引用(作为字典或标签数组)。每次拨打-writeLabels

时都会更新这些标签