簡體   English   中英

內存泄漏-Objective-C

[英]Memory Leaks - Objective-C

誰能幫助指出內存泄漏? 我在這種方法中遇到了很多問題,我不確定到底該如何解決。

- (NSMutableArray *)getTop5AndOtherKeysAndValuesFromDictionary:(NSMutableDictionary *)dict {
    NSLog(@"get top 5");
    int sumOfAllValues = 0;

    NSMutableArray *arr = [[[NSMutableArray alloc] init] retain];

    for(NSString *key in dict){
        NSString *value = [[dict objectForKey:key] retain];
        [arr addObject:value];
        sumOfAllValues += [value intValue];
    }

    //sort values
    NSArray *sorted = [[arr sortedArrayUsingFunction:sort context:NULL] retain];

    [arr release];

    //top 5 values
    int sumOfTop5 = 0;
    NSMutableArray *top5 = [[[NSMutableArray alloc] init] retain];
    for(int i = 0; i < 5; i++) {
        int proposedIndex = [sorted count] - 1 - i;
        if(proposedIndex >= 0) {
            [top5 addObject:[sorted objectAtIndex:([sorted count] - i - 1)]];
            sumOfTop5 += [[sorted objectAtIndex:([sorted count] - i - 1)] intValue];
        }
    }

    [sorted release];

    //copy of all keys
    NSMutableArray *copyOfKeys = [[[NSMutableArray alloc] init] retain];
    for(NSString *key in dict) {
        [copyOfKeys addObject:key];
    }


    //copy of top 5 values
    NSMutableArray *copyOfTop5 = [[[NSMutableArray alloc] init] retain];
    for(int i = 0; i < [top5 count]; i++) {
        [copyOfTop5 addObject:[top5 objectAtIndex:i]];
    }


    //get keys with top 5 values
    NSMutableArray *outputKeys = [[[NSMutableArray alloc] init] retain];
    for(int i = 0; i < [top5 count]; i++) {
        NSString *targetValue = [top5 objectAtIndex:i];
        for(int j = 0; j < [copyOfKeys count]; j++) {
            NSString *key = [copyOfKeys objectAtIndex:j];
            NSString *val = [dict objectForKey:key];
            if([val isEqualToString:targetValue]) {
                [outputKeys addObject:key];
                [copyOfKeys removeObjectAtIndex:j];
                break;
            }
        }
    }


    [outputKeys addObject:@"Other"];
    [top5 addObject:[[NSString stringWithFormat:@"%d",(sumOfAllValues - sumOfTop5)] retain]];


    NSMutableArray *output = [[NSMutableArray alloc] init];
    [output addObject:outputKeys];
    [output addObject:top5];

    NSMutableArray *percents = [[NSMutableArray alloc] init];
    int sum = sumOfAllValues;
    float leftOverSum = sum * 1.0f;

    int count = [top5 count];
    float val1, val2, val3, val4, val5;
    if(count >= 1)
        val1 = ([[top5 objectAtIndex:0] intValue] * 1.0f)/sum;
    else
        val1 = 0.0f;

    if(count >=2)
        val2 = ([[top5 objectAtIndex:1] intValue] * 1.0f)/sum;
    else
        val2 = 0.0f;

    if(count >= 3)
        val3 = ([[top5 objectAtIndex:2] intValue] * 1.0f)/sum;
    else
        val3 = 0.0f;

    if(count >= 4)
        val4 = ([[top5 objectAtIndex:3] intValue] * 1.0f)/sum;
    else
        val4 = 0.0f;

    if(count >=5)
        val5 = ([[top5 objectAtIndex:4] intValue] * 1.0f)/sum;
    else
        val5 = 0.0f;


    if(val1 >= .00001f) {
        NSMutableArray *a1 = [[NSMutableArray alloc] init];
        [a1 addObject:[outputKeys objectAtIndex:0]];
        [a1 addObject:[top5 objectAtIndex:0]];
        [a1 addObject:[NSString stringWithFormat:@"%.01f",(val1*100)]];
        [percents addObject:a1];
        leftOverSum -= ([[top5 objectAtIndex:0] intValue] * 1.0f);
    }
    if(val2 >= .00001f) {
        NSMutableArray *a2 = [[NSMutableArray alloc] init];
        [a2 addObject:[outputKeys objectAtIndex:1]];
        [a2 addObject:[top5 objectAtIndex:1]];
        [a2 addObject:[NSString stringWithFormat:@"%.01f",(val2*100)]];
        [percents addObject:a2];        
        leftOverSum -= ([[top5 objectAtIndex:1] intValue] * 1.0f);
    }
    if(val3 >= .00001f) {
        NSMutableArray *a3 = [[NSMutableArray alloc] init];
        [a3 addObject:[outputKeys objectAtIndex:2]];
        [a3 addObject:[top5 objectAtIndex:2]];
        [a3 addObject:[NSString stringWithFormat:@"%.01f",(val3*100)]];
        [percents addObject:a3];        
        leftOverSum -= ([[top5 objectAtIndex:2] intValue] * 1.0f);
    }
    if(val4 >= .00001f) {
        NSMutableArray *a4 = [[NSMutableArray alloc] init];
        [a4 addObject:[outputKeys objectAtIndex:3]];
        [a4 addObject:[top5 objectAtIndex:3]];
        [a4 addObject:[NSString stringWithFormat:@"%.01f",(val4*100)]];
        [percents addObject:a4];        
        leftOverSum -= ([[top5 objectAtIndex:3] intValue] * 1.0f);
    }
    if(val5 >= .00001f) {
        NSMutableArray *a5 = [[NSMutableArray alloc] init];
        [a5 addObject:[outputKeys objectAtIndex:4]];
        [a5 addObject:[top5 objectAtIndex:4]];
        [a5 addObject:[NSString stringWithFormat:@"%.01f",(val5*100)]];
        [percents addObject:a5];        
        leftOverSum -= ([[top5 objectAtIndex:4] intValue] * 1.0f);
    }

    float valOther = (leftOverSum/sum);
    if(valOther >= .00001f) {
        NSMutableArray *a6 = [[NSMutableArray alloc] init];
        [a6 addObject:[outputKeys objectAtIndex:5]];
        [a6 addObject:[top5 objectAtIndex:5]];
        [a6 addObject:[NSString stringWithFormat:@"%.01f",(valOther*100)]];
        [percents addObject:a6];    
    }

    [output addObject:percents];

    NSLog(@"mu - a");
    //[arr release];
    NSLog(@"mu - b");
    //[copyOfKeys release];
    NSLog(@"mu - c");
    //[copyOfTop5 release];
    NSLog(@"mu - c");
    //[outputKeys release];
    //[top5 release];
    //[percents release];

    return output;  
}

1。

NSMutableArray *arr = [[[NSMutableArray alloc] init] retain];

在objective-c的內存管理中,只有幾種方法可以顯式地遞增1,例如分配,保留,復制,獲取,新建。 如果使用其中任何一種,則將來必須釋放。 您將“ alloc”和“ retain”用於相同的變量“ arr”。

2。

NSString *value = [[dict objectForKey:key] retain];
[arr addObject:value];
sumOfAllValues += [value intValue];

您無需在此“保留”。 同樣,在向數組“ arr”添加值之后,當您釋放“ arr”時,“ arr”將釋放其所有元素。 因此,如果要保留“保留”它,則必須在此for循環的最后一行中[值釋放]。

3。

NSArray *sorted = [[arr sortedArrayUsingFunction:sort context:NULL] retain];

同樣,您不需要“保留”。 如果僅編寫[arr sortedArrayUsingFunction:sort context:NULL],則它將自動為對象提供autorelease選項。 因此,您將來不必擔心“釋放”。

您代碼中的所有其他代碼與前三個代碼都有類似的問題。 只要確保

1.如果您使用了“ alloc”,“ retain”,“ attain”,“ copy”,“ new”,“ mutableCopy”等之一,則將來必須釋放。

2. NSArray和NSMutableArray將在釋放它們時釋放它們的元素。 因此,在添加任何對象並且不需要通過該變量引用之后,最好在添加到數組后釋放它。 其他收集器或容器以相同的方式工作。

3.同樣,如果您將任何UIView實例作為子視圖添加到超級視圖,則該超級視圖將負責其子視圖的內存管理。 換句話說,如果您釋放超級視圖,則其子視圖將自動釋放。

編輯:

4.“保留”用於增加對象的內部計數器。 通常,它用在setter方法中,以將舊變量賦予新變量的所有權。 因此,創建新實例時幾乎幾乎不會使用“保留”。

請糾正我,如果我錯了!

我知道這不會獲得任何支持,因為它沒有具體回答您的問題。 盡管如此,這將是您獲得的最佳建議。 在Mac上讓自己成為出色的Objective-C分析器。 您將再也不會在SO上發布這樣的問題,它將啟發您代碼中的所有錯誤。 我不是在臉頰上吐舌。 嚴重的是,這里沒有人應該嘗試分析您的代碼是否存在內存泄漏。 有些人致力於開發軟件來為您做到這一點。

顯然您的代碼中肯定會存在泄漏。為什么每次初始化時都繼續保留Mutable數組?

您應該嘗試在CLANG(靜態分析器)的幫助下找出內存泄漏。您可以通過在代碼窗口中鍵入cmd + shift + A來實現。

干杯

從靜態分析儀開始-里面有很多東西。 靜態分析儀捕獲了很多。

如果您要提及泄漏的對象,那將真的有幫助。 另外,我懷疑“構建和分析”運行會引導您完成許多(如果不是全部)的過程。

例如, [[[NSMutableArray alloc] init] retain]給您一個擁有兩個保留對象的對象。 這似乎不是您期望的那樣。

參見http://developer.apple.com/library/ios/#documentation/Cocoa/Conceptual/MemoryMgmt/Articles/mmRules.html#//apple_ref/doc/uid/20000994-BAJHFBGH

如果使用名稱以“ alloc”或“ new”開頭或包含“ copy”(例如alloc,newObject或mutableCopy)的方法創建對象,或者向其發送保留消息,則您擁有該對象的所有權。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM