Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What are the best practices to avoid leaks when using objective-c blocks?

I have been working with blocks for a while and I'm trying to be aware of all leaking possible scenarios. I have read a lot about the "retain cycle loop", but I think that maybe there are other possible scenarios. Also, I'm thinking in some simple cases, like: What if you call a block inside a block?; Is different the block memory management if we use ARC or not?; how to find if a block is leaking memory with instruments (or some other tool)?.

like image 282
LuisEspinoza Avatar asked May 13 '13 16:05

LuisEspinoza


People also ask

How do you find memory leaks in Objective-C?

Use Product > Profile in Xcode and then select Leaks.

What is a memory leak Objective-C?

A memory leak occurs when the system is unable to determine if allocated space in memory is in use or not. Both Swift and Objective-C use Automatic Reference Counting (ARC) to manage space in memory. ARC is a memory-management system that keeps track of how many references there are to a given object.

How do blocks work in Objective-C?

Blocks are a language-level feature added to C, Objective-C and C++, which allow you to create distinct segments of code that can be passed around to methods or functions as if they were values. Blocks are Objective-C objects, which means they can be added to collections like NSArray or NSDictionary .


1 Answers

Short answer: Blocks don't inherently introduce any special leak issues (other than retain cycles in special circumstances, described below).

Long answer: A couple of thoughts:

  1. Other than retain cycles (also known as strong reference cycles in ARC) caused if you fail to Avoid Strong Reference Cycles when Capturing self), there really aren't other special leaking risks associated with blocks. If you remember that blocks maintain strong references to objects they reference, then just follow the standard basic rules of memory management.

    As discussed in the Use Lifetime Qualifiers to Avoid Strong Reference Cycles, in MRC you can use the __block qualifier to solve these strong reference cycles, but in ARC, you can use the __weak qualifier.

  2. If you're putting blocks in blocks, that's doesn't introduce any additional leak risks (unless you concoct some circular set of references that causes a strong reference cycle, which is generally unlikely when doing blocks within blocks).

  3. The blocks retain the objects they reference (unless the object is qualified, such as with __block in MRC or with __weak in ARC). The fact that one uses blocks has no bearing on whether the code leaks or not. That's a function of your choice of ARC v MRC and whether you've avoided retain cycles and, if doing MRC, whether you've included the necessary release statements.

  4. In terms of finding leaks, the standard tools all work fine:

    • Especially if doing non-ARC code, the static analyzer (shift+command+B or choose "Analyze" from the "Product" menu) is very useful.

    • The Finding Leaks in Your App discussion in the Instruments User Guide.

    • Sometimes for strong reference cycles, it won't always be flagged by the Leaks tool in instruments. At that point, it's sometimes useful to use the Allocations tool in Instruments, highlight some allocation that you suspect should have been freed but wasn't, and it will show you what allocated that memory. See iOS app with ARC, find who is owner of an object

    • If you're wondering if some object is being deallocated properly, it's useful to add a diagnostic dealloc implementation to your object that should be released:

      - (void)dealloc
      {
          NSLog(@"%s", __FUNCTION__);
      
          // if non-ARC, remember to include the following line, too:
          //
          // [super dealloc];
      }
      

      That way, you'll see a message on your console when the object is deallocated.

  5. If you're worried about leaks, using ARC is (IMHO) one of the easiest way to eliminate many mundane leaks. It's incredibly easy to leak in non-ARC code with a simple omitted release or autorelease (though, admittedly, the above links will help you find them). It's much harder to leak in ARC because of a simple "oh, I forgot to release."

References

  • Blocks Programming Topics

  • Working with Blocks section of the Programming with Objective-C guide

  • The Advanced Memory Management Guide

  • Transitioning to ARC Release Notes

like image 135
Rob Avatar answered Oct 22 '22 19:10

Rob