AliSoftware / Dip

Simple Swift Dependency container. Use protocols to resolve your dependencies and avoid singletons / sharedInstances!
MIT License
978 stars 75 forks source link

Memory issue, registering classes. #159

Closed njall1 closed 7 years ago

njall1 commented 7 years ago

Registering classes have memory issue: screen shot 2017-05-19 at 11 03 20

import Dip

let rootAssembly = DependencyContainer { (container) in
    unowned let container = container

    container.register(.weakSingleton, factory: RootPresenter.init)
        .implements(AnyObject.self,
                    RootModuleInput.self,
                    AppDelegateOutput.self,
                    RootInteractorOutput.self)
        .resolvingProperties { container, presenter in
            presenter.delegate = UIApplication.shared.delegate as! AppDelegate
            presenter.router = try! container.resolve()
            presenter.interactor = try! container.resolve()
            presenter.deeplinkHandler = try! container.resolve()
            presenter.shortcutHandler = try! container.resolve()
    }
...

or

import Dip

let rootAssembly = DependencyContainer { (container) in
    unowned let container = container

    container.register(.weakSingleton, type: RootPresenter.self, factory: RootPresenter.init)
        .implements(AnyObject.self,
                    RootModuleInput.self,
                    AppDelegateOutput.self,
                    RootInteractorOutput.self)
        .resolvingProperties { container, presenter in
            presenter.delegate = UIApplication.shared.delegate as! AppDelegate
            presenter.router = try! container.resolve()
            presenter.interactor = try! container.resolve()
            presenter.deeplinkHandler = try! container.resolve()
            presenter.shortcutHandler = try! container.resolve()
    }
...

or

import Dip

let rootAssembly = DependencyContainer { (container) in
    unowned let container = container

    container.register(.weakSingleton) { RootPresenter() }
        .implements(AnyObject.self,
                    RootModuleInput.self,
                    AppDelegateOutput.self,
                    RootInteractorOutput.self)
        .resolvingProperties { container, presenter in
            presenter.delegate = UIApplication.shared.delegate as! AppDelegate
            presenter.router = try! container.resolve()
            presenter.interactor = try! container.resolve()
            presenter.deeplinkHandler = try! container.resolve()
            presenter.shortcutHandler = try! container.resolve()
    }

I've fixed issue by this way: screen shot 2017-05-19 at 11 09 50

import Dip

let rootAssembly = DependencyContainer { (container) in
    unowned let container = container

    container.register(.weakSingleton, type: RootModuleInput.self, factory: RootPresenter.init)
        .implements(AnyObject.self,
                    AppDelegateOutput.self,
                    RootInteractorOutput.self)
        .resolvingProperties { container, presenter in
            presenter.delegate = UIApplication.shared.delegate as! AppDelegate
            presenter.router = try! container.resolve()
            presenter.interactor = try! container.resolve()
            presenter.deeplinkHandler = try! container.resolve()
            presenter.shortcutHandler = try! container.resolve()
    }
...

or

    container.register(.weakSingleton) { RootPresenter() as RootModuleInput }
        .implements(AnyObject.self,
                    AppDelegateOutput.self,
                    RootInteractorOutput.self)
        .resolvingProperties { container, presenter in
            presenter.delegate = UIApplication.shared.delegate as! AppDelegate
            presenter.router = try! container.resolve()
            presenter.interactor = try! container.resolve()
            presenter.deeplinkHandler = try! container.resolve()
            presenter.shortcutHandler = try! container.resolve()
    }
...

Also issue actual for scopes : shared, singleton, eagerSingleton, weakSingleton.

Please provide any solution, because for me very important registering classes not protocols.

sc0rch commented 7 years ago

Move rootAssembly to Application delegate class. It will fix the most of problems.

njall1 commented 7 years ago

I checked this way and it has not helped. screen shot 2017-05-19 at 11 28 35

import Dip

class AppDelegate: UIResponder, UIApplicationDelegate, AppDelegateInput {

    var window: UIWindow?
    var serviceLocator: ServiceLocator?

    var output: AppDelegateOutput?
    var moduleInput: RootModuleInput?

//    let container: DependencyContainer = rootAssembly

    let container = DependencyContainer { (container) in
        unowned let container = container

        container.register(.weakSingleton) { RootPresenter() }
            .implements(AnyObject.self,
                        RootModuleInput.self,
                        AppDelegateOutput.self,
                        RootInteractorOutput.self)
            .resolvingProperties { container, presenter in
                presenter.delegate = UIApplication.shared.delegate as! AppDelegate
                presenter.router = try! container.resolve()
                presenter.interactor = try! container.resolve()
                presenter.deeplinkHandler = try! container.resolve()
                presenter.shortcutHandler = try! container.resolve()
        }
...
ilyapuchka commented 7 years ago

Can you please state the problem more clear? What is expected, what is actual behaviour?

njall1 commented 7 years ago

Expected: If you register a class with the scope: weakSingleton, there must be one instance of this class in memory.

Actual behaviour: I've registered class with scope: weakSingleton

let container = DependencyContainer { (container) in
    unowned let container = container

    container.register(.weakSingleton) { RootPresenter() }
        .implements(AnyObject.self,
                    RootModuleInput.self,
                    AppDelegateOutput.self,
                    RootInteractorOutput.self)
        .resolvingProperties { container, presenter in
            presenter.delegate = UIApplication.shared.delegate as! AppDelegate
            presenter.router = try! container.resolve()
            presenter.interactor = try! container.resolve()
            presenter.deeplinkHandler = try! container.resolve()
            presenter.shortcutHandler = try! container.resolve()
    }

...

But in memory app has 5 instances of this class. screen shot 2017-05-19 at 11 28 35

Please provide any solution!

ilyapuchka commented 7 years ago

@njall1 unfortunately I can not understand what the issue can be from your code snippets. If you can submit a failing test this will really help.