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

发布于 2024-11-27 07:20:32 字数 2213 浏览 0 评论 0原文

好吧,我知道在这个问题上有很多问题,但在阅读它们并尝试这些方法之后,我的应用程序似乎仍然泄漏内存。我研究了 Apple 内存管理指南 并在此处阅读值得注意的问题,此处此处。我有一个方法可以解析 JSON 字符串,然后将它们返回到 NSMutableDictionary 中。我从返回方法中对对象调用 autorelease ,然后对接收方法调用 retain (确保该对象不会在池的下一个耗尽时释放)。然后当我完成后我会释放然后反对。然而它仍然泄漏。谁能看到我做错了什么吗?

返回方法

+ (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

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. I have a method that parses a JSON string and then returns the them into a 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). 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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

南冥有猫 2024-12-04 07:20:32

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

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

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

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

它应该很简单(同样,如果保留或复制):

self.jsonArray = [SpecialtyUrl parseSpecialtyResult:responseString];

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

You don't release the Speciality objects in the forstatement:

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:

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

It should be simply (again, if retain or copy):

self.jsonArray = [SpecialtyUrl parseSpecialtyResult:responseString];

Also, [super dealloc]; should be the last statement in dealloc.

梦萦几度 2024-12-04 07:20:32

假设 jsonArray 是调用类的 retain 属性,您将添加一个额外的保留:

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

setter 应该已经正确保留和释放。所以保留在那里只会泄漏对象。

其他答案也是正确的,您需要释放专业对象。但只要您过度保留 Specialty 对象所在的数组,泄漏就会一直存在。

Assuming jsonArray is a retain property of the calling class, you're adding an extra retain:

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.

寄意 2024-12-04 07:20:32

你在这条线上泄漏:

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

你创建了一堆专业但你从未发布它们。

在这一行中,您通过在前面使用 self 来过度保留对象 jsonArray 。

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

因为您可能像这样声明了 jsonArray 属性,

@property(nonatomic,retain)...

然后合成了它。它为您创建了一个 setter,当您使用 self 分配对象时,该 setter 会保留该对象。

所以

self.jsonArray = [SpecialtyUrl parseSpecialtyResult:responseString];

就足够了。

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 = [[SpecialtyUrl parseSpecialtyResult:responseString] retain];

Because you probably declared your jsonArray property like:

@property(nonatomic,retain)...

and then you synthezied it. It created a setter for you that retains an object when you assing it using self.

so

self.jsonArray = [SpecialtyUrl parseSpecialtyResult:responseString];

is enough.

心安伴我暖 2024-12-04 07:20:32

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

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

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

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

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). simply assigning the jsonArray to the property will cause a retain to be sent. You can change your code to:

> @property (nonatomic, retain) NSMutableArray  *jsonArray;
> 
> @synthesize jsonArray;
> 
> self.jsonArray = [SpecialtyUrl parseSpecialtyResult:responseString];
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文