Search code examples
swiftmemory-leaksswift3ios10instruments

Leaks in Swift 3 / iOS 10


When I'm running instruments and check for leaks, it's showing leaks mainly consisting of:

_ContiguousArrayStorage<String>
_NativeDictionaryStorageOwner<Int, CGFloat>
_NativeDictionaryStorageOwner<String, AnyObject>

This is when I'm using Swift 3 and testing on devices using iOS 10.

The leaks only show up in iOS 10 while on iOS 9.x everything seems to be normal. On top of that, in iOS 10 UISwitch doesn't seem to deallocate either.

Currently I've been creating all kinds of workarounds trying to avoid using dictionaries and in some cases arrays, making it really annoying to code.

Question:

Should I be concerned about this and try to fix all these leaks or wait and hope it will be fixed in future updates? If so, is there anywhere to check about which bugs are known etc?


Solution

  • I had the same problem and spent a lot of time digging. I found that if you create a Swift object from Objective-C code and the Swift object has a native Swift dictionary property, you will see this leak. It won't happen if all the code is Swift, and more usefully, it won't leak if you change the native Swift dictionary to an NSDictionary. This also applies to Swift Set's and NSSet's. I also saw that the leak happens on iOS 10 and not on iOS 9.

    // LeakySwiftObject.swift
    class LeakySwiftObject: NSObject {
        let dict = [String: String]() // <- Any native Swift dictionary will reproduce the leak
    }
    
    // ObjectiveCObject.h
    @class LeakySwiftObject;
    
    @interface ObjectiveCObject : NSObject
    @property (strong) LeakySwiftObject *leaky;
    @end
    
    // ObjectiveCObject.m
    @implementation ObjectiveCObject
    
    - (instancetype)init
    {
        self = [super init];
        if (self) {
            self.leaky = [LeakySwiftObject new];
        }
        return self;
    }
    
    @end
    
    // ViewController.swift
    class ViewController: UIViewController {
        let testObj = ObjectiveCObject()
    }
    

    The Leaks Instrument reports a leak:
    _NativeDictionaryStorageImpl<String,String>
    _NativeDictionaryStorageOwner<String,String>