目标 c:for 循环变得越来越慢

发布于 2024-11-07 09:53:01 字数 807 浏览 0 评论 0原文

我对 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];

}

I'm quite new to programming for the iPhone/iPad. I have a problem with for-loops, like the one I use in this example. The program works as it should. Only, after every call of the function (in this example - (void) writeLabels), it's getting slower and slower. Can anyone tell me why? In this example, it takes 50 to 100 clicks to notice a delay. But once I pack more instructions into the loop, the program gets too slow thus unusable only after a few clicks. Also an autorelease-pool doesn't help.

- (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];

}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

漆黑的白昼 2024-11-14 09:53:01

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

编辑:按照乔纳的建议,将标签作为班级成员会更好。像这样的东西:

- (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];
        }
}

In the writeLabels method you are adding labels as subviews. But you never removed the previous labels. So after 1st call you have 24 label subviews, after 2nd call you have 48 and so on. The memory consumption will increase in every call, the program will get slow and eventually may crash, though there is no memory leak here. This is not leak, but you are keeping unnecessary things in memory. I guess for the 2nd, 3rd, ... calls the previous labels are not necessary, after all you are creating them in same location in every call. Keep a way to track the added labels (may be by using tags) and before adding new labels remove previous labels from superview.

EDIT: It will be better to have the labels as members of the class as Jonah suggested. Something like this:

- (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];
        }
}
随心而道 2024-11-14 09:53:01

[self.view addSubview:label];

每次调用此方法时,您都会向视图添加一个额外的子视图。您永远不会删除任何这些子视图,因此您的内存使用量只会随着每次方法调用而增加。

而不是每次都创建新标签,只需构建一次即可。在控制器中保留对它们的引用(作为字典或标签数组)。每次调用 -writeLabels 时更新这些标签

[self.view addSubview:label];

You are adding an additional subview to your view every time you call this method. You never remove any of those subviews so your memory use is just going to increase with every method call.

Instead of creating new labels every time construct them once. Keep a reference to them in your controller (as a dictionary or array of the labels). Update those labels every time you call -writeLabels

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文