2011-05-14 156 views
0

我是iPhone/iPad編程的新手。我有一個for循環的問題,就像我在這個例子中使用的那個。該程序的工作原理應該如此。只有在每次調用函數後(在本例中爲 - (void)writeLabels),它纔會變得越來越慢。誰能告訴我爲什麼?在此示例中,需要50到100次點擊才能注意到延遲。但是,一旦我在循環中包含更多指令,程序就會變得太慢,因此只有在幾次點擊後纔會無法使用。另外一個autorelease池並沒有幫助。目標c:for循環變得越來越慢

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

} 

回答

6

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

完全正確,但我認爲使用標籤識別和定位視圖是一種醜陋而脆弱的解決方案。我建議保留對視圖的實際引用。 – Jonah 2011-05-14 16:49:23

+0

非常感謝,這很有道理。但是,因爲我是新的:代碼將如何看起來像? – 2011-05-15 10:57:18

+0

@Andrew,請檢查編輯。希望能幫助到你。 – taskinoor 2011-05-15 12:36:34

4

[self.view addSubview:label];

你加入每次調用此方法時,一個額外的子視圖您的視圖。你永遠不會刪除任何這些子視圖,所以你的內存使用量會隨着每個方法調用而增加。

而不是每構建一次新的標籤。在控制器中保存對它們的引用(作爲字典或標籤數組)。每次撥打電話時更新這些標籤-writeLabels

+0

是的,保持標籤的參考,只更新方法似乎更好。 – taskinoor 2011-05-14 16:51:51