开发者

Memory leak when refreshing table view with retain iOS

开发者 https://www.devze.com 2023-03-11 02:29 出处:网络
Most of the memoryleaks I solved myself, but this one is quite tough imo. The following happens. I need to load information from facebook in a table view, this table view has an refresh function. All

Most of the memoryleaks I solved myself, but this one is quite tough imo. The following happens. I need to load information from facebook in a table view, this table view has an refresh function. All the rows in this tablview are loaded from an array, this arrays consists of data objects as they need to be sorted. My code looks like this (I have cut out the irrelevant parts).

This parts runs through the results from facebook and places it in an array

- (void)request:(FBRequest*)request didLoad:(id)result
{
    if ([result isKindOfClass:[NSDictionary class]]) {  
        //Setting single result into result dictionary
        NSArray *resultArray = [result allObjects];
        result = [resultArray objectAtIndex:0];

        for(int i=0; i<13; i++){  
            //Set all retrieved data in containerArray
           Post *newPost = [[[Post alloc] init] autorelease];
            newPost.created_time = created_time1;
            newPost.message = message1;
            newPost.picture = picture1;
            newPost.fbSource = fbSource1;
            [containerArray insertObject:newPost atIndex:i];

            //Reload the table in the tableView
            [self.tableView reloadData];   
        } 
        NSSortDescriptor *sortDescriptor = [[[NSSortDescriptor alloc] initWithKey:@"created_time" 
                                                                        ascending:NO] autorelease ];    

        sortedArray = [containerArray sortedArrayUsingDescriptors:[NSMutableArray arrayWithObject:sortDescriptor]];      
        [sortedArray retain];
    }
}

So far this works and gives no memory leaks. But as soon as the refresh function gets called. This function will run again. And then creates the memory leak, I think probably due the [sortedArray retain] function. But without this function the array doesn't load and I get a EXC_BAD_ACCESS. If I release sortedArray, I also get the EXC_BAD_ACCESS since the sortedArray is gone and can't be called.

Someone know开发者_Go百科s how to fix this? Thnx!


Your diagnosis is right. If you assign a value to sortedArray a second time the way you are doing, the previous object is leaked.

The solution is calling release before doing the assignment:

    [sortedArray release];
    sortedArray = [containerArray sortedArrayUsingDescriptors:[NSMutableArray arrayWithObject:sortDescriptor]];      
    [sortedArray retain];

A more elegant solution would be declaring sortedArray as a retain property:

   @property (nonatomic, retain) NSArray* sortedArray;

so that you can replace the three lines above by:

    self.sortedArray = [containerArray sortedArrayUsingDescriptors:[NSMutableArray arrayWithObject:sortDescriptor]];      

and this will handle both releasing and retaining properly.


sortedArray = [containerArray sortedArrayUsingDescriptors:[NSMutableArray arrayWithObject:sortDescriptor]];

This line runs for first time and this is OK. But run 2nd time and you are pointing to a new array, leaking the previous one. So there is two solution.

First, release it before this line like this:

[sortedArray release];    
sortedArray = [containerArray sortedArrayUsingDescriptors:[NSMutableArray arrayWithObject:sortDescriptor]];
[sortedArray retain];

Or make sortedArray a retained property in your class.

@property (nonatomic, retain) NSArray *sortedArray;

self.sortedArray = [containerArray sortedArrayUsingDescriptors:[NSMutableArray arrayWithObject:sortDescriptor]];
0

精彩评论

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

关注公众号