Breaking That Cycle
To break a strong reference cycle, define a capture list as part of the closure’s definition. You’ll use a capture list to declare instances captured by closures as being either weak or unowned:
-
Weak: Use this when the captured reference might become
nil
in the future. If the object it refers to is deallocated, the reference becomes nil
. As such, it’s an optional type.
-
Unowned: Use this when the closure and the object it refers to always have the same lifetime and are deallocated at the same time. An unowned reference can still become
nil
, and will be treated as explicitly unwrapped optional, if accessed beyond its lifetime. So use it wisely, when you know it’s not expected to become nil
at the time it’s referenced.
To fix this strong reference cycle, add a capture list to heartToggleHandler
, like this:
resultsCell.heartToggleHandler = { [weak self] _ in
self?.collectionView.reloadItems(at: [indexPath])
}
Declaring self
as weak means SearchResultsViewController
can be deallocated even though the collection view cells hold a reference to it, as they’re now weak references. And deallocating SearchResultsViewController
will deallocate its collection view and, in turn, the cells.
From within Xcode, press Command-I again to build and run the app in Instruments.
Look at the app again in Instruments using Allocations. Remember to filter the results down to show only the classes that are part of the starter project. Perform a search, and navigate into the results and back again. You’ll see that SearchResultsViewController
and its cells are now deallocated when you navigate back. They show transient instances, but no persistent ones.
Cycle broken! Ship it!
Where to Go From Here?
You can download the finished project using the Download Materials button at the top or bottom of this tutorial.
Now that you have the knowledge from this Instruments tutorial under your belt, go and instrument your own code and see what interesting things appear! Also, try to make Instruments a part of your usual development workflow.
Run your code through Instruments often and perform a full sweep of your app before release to ensure you’ve caught as many memory management and performance issues as possible.
For more debugging fun, check out our video course on Intermediate iOS Debugging or read the Advanced Apple Debugging & Reverse Engineering book.
Now, go and make some awesome — and efficient — apps.
We hope you enjoyed this tutorial. If you have any questions or comments, please join the forum discussion below!