3

I'm experiencing some kind of memory management issue. I have a subclass of UIViewController and I set its view manually in order to have a reference back to the viewController and to avoid reference cycle I use weak/unowned. Now the problem is , if I use unowned I have a memory leak but if I use weak I don't have one. I can't figure out why this happens?

update: It seems like it's a bug.

console output:

removing vc
view Controller deinitialized
custom view deinitialized

I'm using xcode 8.3.1

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {

    window = UIWindow(frame: UIScreen.main.bounds)
    window?.rootViewController = ViewController(nibName: nil, bundle: nil)
    window?.makeKeyAndVisible()

    DispatchQueue.main.asyncAfter(deadline: .now() + 5) { 
        print("removing vc")
        self.window?.rootViewController = nil
    }

    return true
}


class ViewController: UIViewController {

    override func loadView() {
        view = CustomView(frame: .zero, vc: self)
        view.backgroundColor = .red
    }

    deinit {
        print("view Controller deinitialized")
    }
}

class CustomView:UIView{

    init(frame: CGRect , vc:ViewController) {
        self.vc = vc
        super.init(frame: frame)
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    //    weak var vc : ViewController!   // no leak
    unowned var vc : ViewController   // leak

    deinit {
        print("custom view deinitialized")
    }
}
  • 1
    How are you determining that you have a leak? Maybe your method is wrong or this is (less likely) a compiler bug – Alistra Apr 14 '17 at 12:33
  • both instruments and memory graph show that, this is a leak. –  Apr 14 '17 at 12:37
  • Neither weak nor unowned hold a strong reference. So it can't be the reason for a leak. see: http://stackoverflow.com/a/26025176/6595536 – ObjectAlchemist Apr 14 '17 at 12:37
  • I know that. But this is the whole code, nothing else can cause the problem and also with weak there is no leak. Maybe it's a bug! –  Apr 14 '17 at 12:40
  • 2
    Please @Alan try to override `deinit` and print some info there and check this way, as the instruments tool for swift may not work properly yet. I personally encountered false positives there. Maybe your leak is not even a leak. – Alistra Apr 14 '17 at 12:40
  • 1
    Do you use Xcode 8.1.3? There was an official problem with the leak tool. Try check again with Xcode 8.2! – ObjectAlchemist Apr 14 '17 at 12:41
  • Might not help you at all, but as a rule of thumb, if you follow MVC pattern, your view shouldn't really be linking back to your view controller like this. For instance, create a delegate protocol to support such communication. – Paulo Mattos Apr 14 '17 at 12:43
  • thanks @Alistra . you're right.it's not a leak. –  Apr 14 '17 at 13:13
  • @PauloMattos . thanks for the hint , but this is part of a bigger problem that mvc can't solve. –  Apr 14 '17 at 13:15
  • as @Alistra said, there is no leak. I have tested it using Instruments Tool. Clearly from apple doc [link] https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/AutomaticReferenceCounting.html. Check for Unowned References section. – Sandeep Apr 14 '17 at 13:34

1 Answers1

3

Xcode 8.2 Release notes:

The Memory Debugger for macOS and the iOS Simulator fixes reporting of false memory leaks for Swift classes containing either fields of type enum, or classes that inherit from certain Objective-C framework classes. (27932061)

ObjectAlchemist
  • 1,109
  • 1
  • 9
  • 18