In this tutorial, I’ll show you how to track down memory leaks within Xcode via the Memory Graph Debugger, new since Xcode 8. This is a powerful visual tool and doesn’t require you to step out of Xcode and start the Leaks Instrument. Once we identify some memory leaks, I’ll show you how to plug those leaks by using the Swift language’s
unowned qualifiers, and talk about the differences between the two qualifiers.
I recently discussed iOS memory management and memory leaks that occur when using reference semantics and reference types (classes) in my tutorials on “Swift 4 memory management via ARC for reference types (classes)” and “Fixing memory leaks — strong reference cycles — in Swift 4.” After reading these articles, you should understand how easy it is to inadvertently encode and introduce a strong reference cycle into your Swift 4 code and thus end up with a memory leak. You should also understand how generally straightforward it is to fix such a memory leak. My sample code in both tutorials was didactic. What about real-world projects with hundreds of thousands or millions of lines of code? Suppose that you’ve heard reports of diminished app performance, low memory warnings, or just plain app crashes. Finding memory leaks in your code is quite cumbersome when trying to debug via rote inspection, setting breakpoints, adding logging statements, etc.
Continue reading “Finding memory leaks with the Xcode Memory Graph Debugger and fixing leaks with unowned and weak”
PREREQUISITES FOR THIS TUTORIAL
If you don’t understand how Swift manages memory for classes (reference types), you need to read the first article in this series, “Swift 4 memory management via ARC for reference types (classes)”. Once you understand how reference type-based memory is managed with ARC, you’ll be ready to understand how to prevent memory leaks from occurring in your app. Remember that ARC only applies to reference (
class) types, not value types like
THE ARC DEALLOCATION PROCESS
Remember how we visualized the reference count that ARC maintains on the allocated instance of reference type
Widget in my introductory ARC tutorial?
// reference count is zero; nothing allocated
widgetReference = Widget(name: "eraser", manufacturer: "Acme")
// reference count is now 1
widgetReference1 = widgetReference
// reference count is now 2
widgetReference2 = widgetReference
// reference count is now 3
widgetReference = nil
// reference count is now 3-1 = 2
widgetReference1 = nil
// reference count is now 2-1 = 1
widgetReference2 = nil
// reference count is now 1-1 = 0
Continue reading “Fixing memory leaks — strong reference cycles — in Swift 4”
Most developers assume that Swift is a “safe” language in terms of memory management. That’s probably true most of the time, but there are some notable exceptions, especially when dealing with certain scenarios when using what are called “reference types” and “reference semantics.”
This tutorial is ultimately meant to prepare you for in-depth discussion of what seems to be inevitable shift from reference semantics to value semantics. Before I plunge into this software development paradigm shift, I want to provide you with a strong and understanding of how memory is managed when you create and use instances of the
class type, a reference type. Oftentimes, reference-based memory management “just works” … until it doesn’t. Things don’t work mainly in situations where
class types are designed with interdependencies and/or when multiple threads access the same instance (object) of a
class type, and you get “memory leaks.” Swift manages reference-based memory with a technology Apple has dubbed “Automatic Reference Counting” (ARC). Before even begin talking about debugging memory leaks, you must understand ARC.
This discussion does not pertain to memory management for value types (
enum), but note that I will mention value types and value semantics several times in terms of comparison to reference types and reference semantics.
Continue reading “Swift 4 memory management via ARC for reference types (classes)”