好的,所以我知道在这个问题上有一堆问题,但在阅读它们并尝试使用这些方法之后,我的应用程序似乎仍然会泄漏内存。我研究过Apple Guide on Memory Manegment并阅读了值得注意的问题here,here和here。我有一个解析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
答案 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];