简体   繁体   English

Objective C泄漏自动释放对象上的内存

[英]Objective C Leaks memory on Autoreleased Object

Ok so I know there are a bunch of questions asked on this issue but after reading them and trying the methods out, my app still seems to leak memory. 好的,所以我知道对此问题有很多疑问,但是在阅读并尝试了这些方法之后,我的应用似乎仍然会泄漏内存。 I have studied the Apple Guide on Memory Manegment and read notable questions here , here and here . 我已经研究了《 Apple内存管理指南》 ,并 此处此处此处阅读了值得注意的问题。 I have a method that parses a JSON string and then returns the them into a NSMutableDictionary . 我有一个解析JSON字符串,然后将它们返回到NSMutableDictionary I call autorelease on the object from the returning method and then call retain on the receiving method (ensuring that the object is not dealloc on the next drain of the pool). 我从返回方法中调用对象的autorelease ,然后在接收方法中调用retain (确保对象不会在下一个池中autorelease )。 Then I release then object when I am done with it. 完成后,我释放对象。 However it still leaks. 但是它仍然泄漏。 Can anyone see what I am doing wrong? 谁能看到我在做什么错?

Return Method 退货方式

+ (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];
}

Calling Class 呼叫班

- (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]);
}

Log 日志记录

Ref count 1

You don't release the Speciality objects in the for statement: 您不会在for语句中释放Speciality对象:

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

Also, if jsonArray is a retain or copy property, this over-retains the object: 另外,如果jsonArray是保留或复制属性,则此对象将过度保留:

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

It should be simply (again, if retain or copy): 它应该很简单(同样,如果保留或复制):

self.jsonArray = [SpecialtyUrl parseSpecialtyResult:responseString];

Also, [super dealloc]; 另外, [super dealloc]; should be the last statement in dealloc . 应该是dealloc的最后一条语句。

Assuming jsonArray is a retain property of the calling class, you're adding an extra retain: 假设jsonArrayretain调用类的属性,要添加一个额外的保留:

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

The setter should already be properly retaining and releasing. 装订机应已正确保留和释放。 So that retain there just leaks the object. 这样保留在那里只是泄漏对象。

The other answers are also correct that you need to release the Specialty objects. 其他答案也是正确的,您需要释放特殊对象。 But the leak will remain either way as long as you're overretaining the array that the Specialty objects are in. 但是只要您过度保留Specialty对象所在的数组,泄漏就仍然会保留。

You are leaking on this line: 您在此行上泄漏:

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

You create a bunch of specialities but you never release them. 您创建了很多专业,但从未发布过。

And on this line you are overretaining the object jsonArray by using self in front. 在这一行上,您通过在前面使用self来保留对象jsonArray。

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

Because you probably declared your jsonArray property like: 因为您可能像这样声明了jsonArray属性:

@property(nonatomic,retain)...

and then you synthezied it. 然后您将其合成。 It created a setter for you that retains an object when you assing it using self. 它为您创建了一个setter,当您使用self进行对象设置时,它会保留一个对象。

so 所以

self.jsonArray = [SpecialtyUrl parseSpecialtyResult:responseString];

is enough. 足够。

When you take owner ship of the object here, you might be getting two retain messages. 当您在此处获取对象的所有者时,可能会收到两条保留消息。

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

if the jsonArray property is declared as (retain) or (nonatomic, retain). 如果jsonArray属性声明为(保留)或(非原子,保留)。 simply assigning the jsonArray to the property will cause a retain to be sent. 简单地将jsonArray分配给该属性将导致发送保留。 You can change your code to: 您可以将代码更改为:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM