开发者

objective c: for-loop gets slower and slower

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 whit开发者_如何学编程eColor];

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

}


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


[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

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜