内存泄漏 - 目标-C

Cod*_*Guy 0 memory iphone memory-leaks objective-c ios

任何人都可以帮助指出内存泄漏?我在这个方法中得到了很多,我不确定如何修复它.

- (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;  
}
Run Code Online (Sandbox Code Playgroud)

pnm*_*nmn 6

1.

NSMutableArray *arr = [[[NSMutableArray alloc] init] retain];
Run Code Online (Sandbox Code Playgroud)

在objective-c的内存管理中显式增加1的方法很少,例如alloc,retain,copy,obtain,new.如果您使用其中任何一种,则必须在将来发布.您对同一个变量"arr"使用了"alloc"和"retain".

2.

NSString *value = [[dict objectForKey:key] retain];
[arr addObject:value];
sumOfAllValues += [value intValue];
Run Code Online (Sandbox Code Playgroud)

你不需要"保留"那里.在向数组"arr"添加值之后,"arr"将在您释放"arr"时释放其ALL元素.所以如果你想保持"保留"它,你必须在这个for循环的最后一行[value release].

3.

NSArray *sorted = [[arr sortedArrayUsingFunction:sort context:NULL] retain];
Run Code Online (Sandbox Code Playgroud)

同样,你不需要"保留".如果只编写[arr sortedArrayUsingFunction:sort context:NULL],那么它将自动为对象提供autorelease选项.因此,您将来不必关心"发布".

代码中的所有其他代码都与前三个问题类似.请确保

1.如果您使用了"alloc","retain","getting","copy","new","mutableCopy"等等,则必须在将来发布.

2. NSArray和NSMutableArray将在您释放它们时释放它们的元素.因此,在添加任何对象并且不需要通过该变量引用之后,最好在添加到数组后释放.其他收集器或容器以相同的方式工作.

3.同样,如果您将任何UIView实例作为子视图添加到superview,那么该superview将关注其子视图的内存管理.换句话说,如果您发布超级视图,其子视图将自动发布.

编辑:

4."retain"用于递增对象的内部计数器.通常,它在setter方法中用于将旧变量的所有权赋予新变量.因此,在创建新实例时,几乎不会使用"保留".

如果我错了,请纠正我!

  • 我是+1,因为你实际上已经完成了他的代码,并试图解释为什么它是错的.对于这个问题的未来,我强烈建议的一件事是解释开发人员何时想要使用retain.他犯了使用它的错误,这意味着它的用法并不清楚.如果你能用时间和地点修改你的答案,我相信你会成为公认的答案. (3认同)