5

I'm running into what looks like a memory leak using Swift on iOS.

Here's a pared-down runnable example — you can tap the screen to show a share sheet, and BadActivity will leak every time.

import UIKit

class ViewController: UIViewController {
    override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
        let activity = ShareController(activityItems: [""],  applicationActivities: [BadActivity(), GoodActivity()])
        self.showViewController(activity, sender: nil)
    }
}

class ShareController: UIActivityViewController {
    deinit { print("ShareController deinit.") }
}

class GoodActivity: UIActivity {
    override func activityTitle() -> String { return "Good" }
    deinit { print("Good deinit. This is printed.") }
}

class BadActivity: UIActivity {
    override func activityTitle() -> String { return "Bad" }
    deinit { print("Bad deinit. This is never printed.") }

    override func canPerformWithActivityItems(activityItems: [AnyObject]) -> Bool {
        return true
    }

    override func performActivity() {
        self.activityDidFinish(true)
    }
}

Regardless of whether you cancel the dialog or press export, BadActivity is instantiated but never deallocated – the console output is ShareController deinit. Good deinit.

If you make BadActivity.canPerformWithActivityItems return false instead of true, however, it deallocates normally.

yurivish
  • 51
  • 3
  • I have the same issue when I use objective-c. I'm not sure what's the reason. Do you figure out how to resolve this? – Vincent Jul 22 '16 at 07:45
  • 1
    I ended up initializing just one UIActivityController and implementing custom mutable UIActivityItemSources so that I can use the same instance of the controller over time, but change the behavior of the UIActivities that I passed into it. Very hacky, but it solved the problem. – yurivish Jul 23 '16 at 17:24

0 Answers0