简体   繁体   中英

Typhoon with singleton AppDelegate

I'm using typhoon with 'Plist integration'

I've defined the AppDelegate as follows inside an assembly:

- (AppDelegate *)appDelegate {
    return [TyphoonDefinition withClass:[AppDelegate class] configuration:^(TyphoonDefinition *definition) {
        [definition injectProperty:@selector(window)];
        definition.scope = TyphoonScopeSingleton;
    }];
}

Inside window , I have a rootViewController with a delegate that it's implemented by AppDelegate .

- (RootViewController *)rootViewController {
    return [TyphoonDefinition withClass:[RootViewController class] configuration:^(TyphoonDefinition *definition) {
        [definition injectProperty:@selector(delegate)]; 
    }];
}

The problem is that the delegate is set with another instance of AppDeleaate . I've set a breakpoint inside the AppDelegate init and indeed it's called twice.

I know that a solution would be to manually set the delegate inside the AppDelegate during runtime, but I would like this to be handled by typhoon.

Note: I haven't tried it but this same thing may happen with view controllers created by storyboards.

Good question.

Typhoon didn't inject your initial AppDelegate since it was created outside Typhoon. Typhoon has inetrnal pool of objects and they are used to inject into another objects, if Typhoon hasn't object in pool, it would be created using specified initializer (and retained if scope is singleton).

ViewControllers created from storyboard will be injected correctly, since they are created inside Typhoon.

To solve your particular problem try this definition for AppDelegate:

- (AppDelegate *)appDelegate {
    return [TyphoonDefinition withClass:[AppDelegate class] configuration:^(TyphoonDefinition *definition) {
        [definition setFactory:[self sharedApplication]];
        [definition useInitializer:@selector(delegate)];
        [definition injectProperty:@selector(window)];
        definition.scope = TyphoonScopeSingleton;
    }];
}

- (UIApplication *)sharedApplication {
    return [TyphoonDefinition withClass:[UIApplication class] configuration:^(TyphoonDefinition *definition) {
        [definition useInitializer:@selector(sharedApplication)];
    }];
}

Then during resolving appDelegate definition, Typhoon will call [[UIApplication sharedApplication] delegate] method and register returned instance in Typhoon.

With that way, AppDelegate will be created only once (by UIApplication).. But injections will be applied twice (one duting startup, second one when resolving appDelegate definition first time)

Update

AppDelegate case fixed inside Typhoon. Your original code will works now (with head version or in future release).

This seems to have broken again in 8.4.

When doing the Typhoon plist integration, you end up with 2 AppDelegates. The one create by UIApplication and the one managed by Typhoon.

I switched over from how the current Typhoon docs say to create the appDelegate:

public dynamic func appDelegate() -> AnyObject {
return TyphoonDefinition.withClass(AppDelegate.self) {
  (definition) in

  // load up any environment variables/injections
  definition.injectProperty("assembly", with: self)
  definition.injectProperty("window", with: UIWindow(frame: UIScreen.mainScreen().bounds))
  definition.scope = TyphoonScope.LazySingleton
}  

To doing it IAW with Alekseys 's answer.

This fixed the 2x AppDelegate issue, but that leaves a chicken and egg issue; specifically that the AppDelegate is created by UIApplication before the Typhoon Assembly is created via plist. So that if your view controllers are managed by Typhoon, not via storyboard, they won't exist during your appDelegate's didFinishLaunchingWithOptions setup phase.

To fix this, I ended up making the Typhoon Assembly a normal singleton, and removing the plist integration.

I hope this helps people struggling with the same issue.

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