简体   繁体   中英

Lazily instantiate dependencies using DI in iOS (Typhoon & Objection)

I am a huge fan of dependency injection pattern but I am a little sceptical when it comes to following this pattern in mobile development and the main reason being memory allocation. I will briefly explain what my concern is:

I am using DI in my Objective-C based iOS project. I have used both Objection and Typhoon but could not find a way to lazily instantiate the dependencies (not talking specifically about Singletons). I get my dependencies injected even if the use case flow of the app does not require the object to be allocated. As soon as I call injectDependencies: method (Objection) or plist Integration (Typhoon) all the dependencies are injected. Although Objection site mentions it lazily loads everything but I didn't see a proof of that. Is there a way to lazy load the dependencies using these frameworks? For example, I want something like this:

@property (nonatomic) MyClass *classObject;

- (void)viewDidLoad
{
    [super viewDidLoad];

    // Check at this point that classObject should be nil

    id str = classObject.myString;

    // As soon as the getter is called, the property is first instantiated and then returned a value.
}

Is DI meant to be this way? If yes then doesn't this pattern defies the memory allocation thumb rule for mobile (allocate only when you need it)?

Typhoon founder here.

Dependency Injection on Server Side Projects

When we use Dependency Injection with server-side frameworks, the default scope is singleton. This makes sense, given that the server could be expected to serve any use-case at a given point in time.

Dependency Injection on Mobile And Desktop

In iOS we may have some background (singleton) components, however we're typically focusing on one use case at a time. Therefore, Typhoon introduces the unique TyphoonScopeObjectGraph as the default among its scopes .

With TyphoonScopeObjectGraph means that the relationship between dependencies are described, a Typhoon will create a shared instance only while the object graph is being solved . This means you can wire-up a complex object graph using circular dependencies (delegate pattern) and so forth. Typhoon then hands this entire object graph to whatever will be using it, and releases ownership.

Normal Objective-C runtime rules apply from here - if the controller or whatever is using the built object-graph has a strong property, then the graph will be retained in memory as long as that view controller is.

In this way we can proceed from one object graph (use-case) to another, while preserving memory on resource constrained devices.

Other Scopes

Typhoon also includes the following additional scopes besides the default:

  • TyphoonScopeSingleton - retained by the DI container. Use for background daemons and so forth.
  • TyphoonScopeLazySingleton - like a regular singleton, but instantiation is delayed until the first time it is used. (I believe Objection singletons work like this).
  • TyphoonScopeWeakSingleton - instantiated and shared as long as at least one object is retaining it, then destroyed. Will be re-instantiated the next time it is requested again.
  • TyphoonScopePrototype - always creates a new instance, even during a single solve cycle.

Proceeding from One Object Graph to Another:

A typhoon built story board can load another object-graph, such as another view controller to proceed to a new use-case 'on-demand'. To do this we Typhoon as a factory class, and inject the assembly itself , optionally. We can then ask Typhoon to build an instance of the required class. If you wish you can back your assembly with a protocol, so that your class is not coupled directly to Typhoon.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM