调用者此时不拥有的对象的引用计数的不正确的减少

时间:2011-03-15 14:11:34

标签: iphone xcode memory nsstring trim

iPhone上的调用者此时不拥有的对象的引用计数的不正确的减少。它发生在NSString,我明确地在for循环中初始化和释放。我试图像autoreleases字符串一样做,但我得到了泄漏。我认为罪魁祸首是stringbytrimming调用。任何建议,顺便说一下这不泄漏,但我在构建和分析中得到警告。一切都运行良好,应用程序不会崩溃。

for(int i=0;i<storyQuantity;i++) {
            NSString *imageString = [[NSString alloc] init];
            imageString = [[[storiesArray objectAtIndex:i] objectForKey: @"image"] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];  // must add trimming to remove characters

            imageLoader *imageOperation = [[imageLoader alloc] initWithImageURL:imageString target:self action:@selector(didImageLoad:) number:i];

            AppDelegate_iPad *appDelegate = [[UIApplication sharedApplication] delegate];
            [appDelegate.queue_ addOperation:imageOperation];
            [imageOperation release];
            [imageString release];
        }

UPDATE - 添加了我的imageLoader类,据我所知,这个类没有泄漏

- (id)initWithImageURL:(NSString *)url target:(id)target action:(SEL)action number:(int)number {
    if(self = [super init]) {
        _action = action;
        _target = target;
        _number = number;
        if(url == nil) {
            return nil;
        } else {
            _imgURL = [[NSURL alloc] initWithString:[url copy]];
        }
    }
    return self;
}

- (id)main {

    NSAutoreleasePool *pool = [NSAutoreleasePool new];

    if ([self isCancelled]) {
        NSLog(@"OPERATION CANCELLED");
        [UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
        [pool drain];
        return nil;
    } else {

        [UIApplication sharedApplication].networkActivityIndicatorVisible = YES;

        NSData *imgData = [[NSData alloc] initWithContentsOfURL:_imgURL];
        UIImage *image = [[UIImage alloc] initWithData:imgData];
        [imgData release];

        if ([self isCancelled]) {
            NSLog(@"OPERATION CANCELLED");
            [image release];
            [UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
            [pool drain];
            return nil;
        } else { 

            NSNumber *tempNumber = [NSNumber numberWithInt:_number];
            NSDictionary *tempDict = [NSDictionary dictionaryWithObjectsAndKeys:tempNumber, @"number", image, @"image", nil];
            [image release];

            if([_target respondsToSelector:_action])
                [_target performSelectorOnMainThread:_action withObject:tempDict waitUntilDone:NO];
        }
    }

    [pool drain];
    return nil;

}

- (void)dealloc {
    [_imgURL release];
    [super dealloc];
}

2 个答案:

答案 0 :(得分:5)

由于您要重新分配imageString变量,因此对原始对象的引用将丢失。为什么还要分配一个空字符串?只需将代码更改为

即可
NSString *imageString = [[[storiesArray objectAtIndex:i] objectForKey: @"image"]
   stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];

并移除[imageString release],你就可以了。

答案 1 :(得分:1)

不要将引用计数作为理解内存管理的一种方法。这只会让你感到困惑。事物从框架深处操纵对象的参考计数,如果你看到这些数字(显然)没有理由跳过,你就会疯狂地发布一系列越来越疯狂的问题,然后我们会有处理。相信我 - 我们以前见过它。

因此,请忽略引用计数,并确保正确保留和释放对象。