1

Passing an NSDictionary literal as the object to -performSelector:onThread:withObject:waitUntilDone: will cause it to crash as the other thread's run loop's autoreleasepool will attempt to release it.

What is the best way to deal with this issue? Simply retain the object or is there a better practice?

(Goes without saying that this project does not use ARC.)

Matoe
  • 2,742
  • 6
  • 33
  • 52

1 Answers1

0

The dictionary will not be added others thread 's autorelease pool, unless you explicitly call [dictionary autorelease] on that thread.

It's probably the original thread's autorelease pool that releases the object. When you create a NSDictionary instance using literal syntax, it is autoreleased (+[NSDictionarydictionaryWithObjects:forKeys:count:] is called under the hood).

The old NSObject documentation I've found says (about performSelector:onThread:withObject:waitUntilDone:)

This method retains the receiver and the arg parameter until after the selector is performed

So you have to over-release the dictionary somewhere.

I would use Grand Central Dispatch instead of performSelector methods. The blocks implicitly retain the variables they capture, so in most cases you don't have to worry about the memory management:

NSDictionary *dictionary = @{@"foo" : @"bar"};
  dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    //do something with the dictionary
    [dictionary description];
    //if needed, do something on main thread once the background work is finished
    dispatch_sync(dispatch_get_main_queue(), ^{
      //...
    });
  });
Michał Ciuba
  • 7,876
  • 2
  • 33
  • 59