Ilya Ilin
Ilya Ilin

Reputation: 2401

Why does this GCD example code seem to improperly release an object?

In wikipedia example author has released the object stats, when it has not been allocated, copied, or retained. Is this an error or something I don't understood?

- (IBAction)analyzeDocument:(NSButton *)sender
{
  dispatch_async(dispatch_get_global_queue(0, 0), ^{
    NSDictionary *stats = [myDoc analyze];
    dispatch_async(dispatch_get_main_queue(), ^{
      [myModel setDict:stats];
      [myStatsView setNeedsDisplay:YES];
      [stats release];
    });
  });
}

Upvotes: 0

Views: 154

Answers (3)

Joe
Joe

Reputation: 57169

It is either an error or it is properly documented that analyze returns ownership of the object to the caller. If it is not an error that stats is released then that codes example is using a convention that goes against Apple's memory management rules for ownership.

Memory-management rules, sometimes referred to as the ownership policy, help you to explicitly manage memory in Objective-C code.

You own any object you create by allocating memory for it or copying it.
Related methods: alloc, allocWithZone:, copy, copyWithZone:, mutableCopy, mutableCopyWithZone:

Another prefix that should return ownership is the class method +new. E.g. [MyDocClass newAnalysis];

Upvotes: 2

Craig Siemens
Craig Siemens

Reputation: 13276

Most likely analyze is returning a dictionary with a retain count of 1 which is why the release is needed.

Upvotes: 1

jscs
jscs

Reputation: 64002

This is just an example cooked up by John Siracusa to demonstrate how GCD can easily put a long-running task into the background, but, yes, it has one of two problems, one an ingored convention, the other an actual error.

It's possible that the fictional analyze method returns an owning reference. This is a violation of Cocoa convention that methods not named new, alloc, release, or copy... generally don't return such references, but if the documentation made clear that it did, and there was really no way around it, it could be all right. In this case, sending release to stats would be necessary to avoid a memory leak. (If this were real code, renaming the method would be a good idea, perhaps using create which is used in CoreFoundation to signify return of an owning reference.)

If, however, analyze follows convention and returns a non-owned reference, then you're right, sending release to stats is incorrect and will eventually cause a crash.

Upvotes: 2

Related Questions