简体   繁体   中英

Memory issue when calling dispatch_async with local variable

I am having issues in code when calling dispatch_async. I think that issue is due to ARC reclaiming the object, before it is used in a block, as the method that dispatches it finishes.

- (void) method:(SomeClass *) someClass {
  // local variable
  NSNumber *someValue = someClass.somePropertyOnManagedObject;
  dispatch_async(queue, ^() {
    /* call some singleton object passing variable 
     * when access the variable, reference is nil
     */
    [[DashboardFacade sharedInstance] someMethod:someValue];
  });
}

After having looking through much documentation, I conclude

  • Block accesses no parameters – nothing to discuss
  • Block accesses simple type parameters eg BOOL, int - these are copied and not a problem
  • Block accesses parameter of method that dispatched it - I am not sure, but think that this is ok
  • Block accesses property of self – as long as self “lives” until the call has finished ok
  • Block accesses local variable in method that dispatched it
    • If we use some semaphores such that we wait for the block to return before leaving the method, then all ok
    • Otherwise variable may have been garbage collected before block can use.

I think that the solution is to use __block modifier such that ARC retains the variable.

My question is

  • Is the above technically correct, eg using __block will resolve the problem and not introduce other problems?
  • Why can't I find this anywhere on the internet/google?

Is the above technically correct, eg using __block will resolve the problem and not introduce other problems?

Yes it's technically correct, __block , on ARC, allows you to change the variable (in this case to where its pointing, since it's a NSNumber * ), that was declared outside the block context.

Why can't I find this anywhere on the internet/google?

I think the problem is not related to this particular place of your code, but something else.

someValue inside the block can be nil only if it is nil after this assignment:

NSNumber *someValue = someClass.somePropertyOnManagedObject;

Blocks retain objects that are being captured by the blocks as a result of those variables being used inside the blocks. And it doesn't matter if it is self or a local variable from the scope that is visible to the block.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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