目标C泄漏自动释放对象的内存

时间:2011-07-29 20:16:09

标签: iphone objective-c ios memory-management autorelease

好的,所以我知道在这个问题上有一堆问题,但在阅读它们并尝试使用这些方法之后,我的应用程序似乎仍然会泄漏内存。我研究过Apple Guide on Memory Manegment并阅读了值得注意的问题hereherehere。我有一个解析JSON字符串的方法,然后将它们返回到NSMutableDictionary。我从返回的方法中调用对象上的autorelease,然后在接收方法上调用retain(确保对象在池的下一个排水管上不是dealloc)。然后,当我完成它时,我释放对象。但它仍然泄漏。谁能看到我做错了什么?

退货方式

+ (NSMutableArray *)parseSpecialtyResult:(NSString *)json
{
    SBJsonParser *parser = [[SBJsonParser alloc] init];

    NSDictionary *dictionary = [parser objectWithString:json];

    NSArray *jsonObjects = [dictionary valueForKey:@"Rows"];

    NSMutableArray *jsonArray = [[NSMutableArray alloc] initWithCapacity:[jsonObjects count]];

    //Storing objects
    for (NSDictionary *dict in jsonObjects) 
    {
        Specialty *specialty = [[Specialty alloc] init];
        [specialty setName:[dict objectForKey:@"name"]];
        [specialty setIdenity:[dict objectForKey:@"id"]];

        [jsonArray addObject:specialty];
    }

    [parser release];

    //Relinquish ownership of this object
    return [jsonArray autorelease];
}

致电课程

- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
    [connection release];

    NSString *responseString = [[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding];
    [responseData release];

    //This class will take the responsibility of the object's ownership
    self.jsonArray = [[SpecialtyUrl parseSpecialtyResult:responseString] retain];

    [tableView reloadData];

    [responseString release];
}

- (void)dealloc
{
    [super dealloc];
    //No longer need the object
    [jsonArray release];
    NSLog(@"Ref count %i", [jsonArray retainCount]);
}

日志

Ref count 1

4 个答案:

答案 0 :(得分:5)

您不会在Speciality语句中释放for个对象:

for (NSDictionary *dict in jsonObjects) 
{
    Specialty *specialty = [[Specialty alloc] init];
    ...
    [jsonArray addObject:specialty];
    [specialty release];
}

此外,如果jsonArray是保留或复制属性,则会过度保留对象:

self.jsonArray = [[SpecialtyUrl parseSpecialtyResult:responseString] retain];

应该简单(再次,如果保留或复制):

self.jsonArray = [SpecialtyUrl parseSpecialtyResult:responseString];

此外,[super dealloc];应该是dealloc中的最后一个语句。

答案 1 :(得分:3)

假设jsonArray是调用类的retain属性,那么您需要添加额外的保留:

self.jsonArray = [[SpecialtyUrl parseSpecialtyResult:responseString] retain];
                                                                        ^ 
                                                                   Right here!

设定者应该已经正确保留和释放。因此保留那里只是泄漏了对象。

其他答案也是正确的,您需要释放Specialty对象。但只要你保留了Specialty对象所在的数组,泄漏就会保持不变。

答案 2 :(得分:0)

你在这条线上泄露:

Specialty *specialty = [[Specialty alloc] init];

你创造了一堆专业,但你永远不会释放它们。

在这一行上,你通过在前面使用self来重新获得对象jsonArray。

self.jsonArray = [[SpecialtyUrl parseSpecialtyResult:responseString] retain];

因为您可能声明了jsonArray属性,如:

@property(nonatomic,retain)...

然后你合成它。它为您创建了一个setter,当您使用self进行协助时,它会保留一个对象。

所以

self.jsonArray = [SpecialtyUrl parseSpecialtyResult:responseString];

就够了。

答案 3 :(得分:0)

当您在此处获取对象的所有者时,您可能会收到两条保留消息。

 //This class will take the responsibility of the object's ownership
 self.jsonArray = [[SpecialtyUrl parseSpecialtyResult:responseString] retain];

如果jsonArray属性声明为(retain)或(nonatomic,retain)。简单地将jsonArray分配给属性将导致发送保留。您可以将代码更改为:

> @property (nonatomic, retain) NSMutableArray  *jsonArray;
> 
> @synthesize jsonArray;
> 
> self.jsonArray = [SpecialtyUrl parseSpecialtyResult:responseString];