Тайфун + Свифт: сбой при использовании аргументов во время выполнения
В настоящее время я пытаюсь в Typhoon добавить Dependency Injection в мое приложение, которое сейчас наполовину Swift, наполовину устаревшее Objective-C. Я пытаюсь создать экземпляр контроллера вида из раскадровки в моей сборке, но работаю в случае сбоя ниже. Я прочитал здесь https://github.com/appsquickly/Typhoon/issues/293 что использование NSString решит проблему, но, как вы можете видеть ниже, я уже сделал это, и это не совсем помогает... Есть идеи?
dynamic func typhoonStoryboard(name: NSString) -> AnyObject {
return TyphoonDefinition.withClass(TyphoonStoryboard.self, configuration: { (definition) -> Void in
definition.useInitializer("storyboardWithName:factory:bundle:", parameters: { (initializer) -> Void in
initializer.injectParameterWith(name)
initializer.injectParameterWith(self)
initializer.injectParameterWith(NSBundle.mainBundle())
})
})
}
dynamic func viewController(withStoryboardName storyboardName: NSString, storyboardIdentifier: NSString) -> AnyObject {
return TyphoonDefinition.withFactory(self.typhoonStoryboard(NSString(string: storyboardName)), selector: "instantiateViewControllerWithIdentifier:", parameters: { (method) -> Void in
method.injectParameterWith(NSString(string: storyboardIdentifier))
}, configuration: { (definition) -> Void in
})
}
Есть идеи, что может быть не так? Как вы видите, я уже делаю обходной путь с NSString, но он по-прежнему аварийно завершает работу со следующим исключением...
2015-09-15 09:26:32.484 MyApp[64855:5393006] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'You can't call a method on the runtime argument being passed in. It has to be passed in as-is'
*** First throw call stack:
(
0 CoreFoundation 0x000000010ae0ff65 __exceptionPreprocess + 165
1 libobjc.A.dylib 0x000000010a42edeb objc_exception_throw + 48
2 CoreFoundation 0x000000010ae0fe9d +[NSException raise:format:] + 205
3 MyApp 0x00000001052282b3 -[TyphoonInjectionByRuntimeArgument forwardingTargetForSelector:] + 67
4 CoreFoundation 0x000000010ad65c4e ___forwarding___ + 158
5 CoreFoundation 0x000000010ad65b28 _CF_forwarding_prep_0 + 120
6 libswiftCore.dylib 0x000000010bff54b3 _TTSf4g_d___TFSSCfMSSFT12_cocoaStringPSs9AnyObject__SS + 131
7 libswiftCore.dylib 0x000000010bfbce33 _TFSSCfMSSFT12_cocoaStringPSs9AnyObject__SS + 19
8 libswiftFoundation.dylib 0x000000010c3e0af9 _TToFE10FoundationCSo8NSStringcfMS0_FT6stringS0__S0_ + 41
9 libswiftFoundation.dylib 0x000000010c3e0a3a _TFE10FoundationCSo8NSStringCfMS0_FT6stringS0__S0_ + 58
10 MyApp 0x0000000104cc890d _TFC8MyApp22ViewControllerAssembly14viewControllerfS0_FT18withStoryboardNameCSo8NSString20storyboardIdentifierS1__PSs9AnyObject_ + 157
11 MyApp 0x0000000104cc90cf _TToFC8MyApp22ViewControllerAssembly14viewControllerfS0_FT18withStoryboardNameCSo8NSString20storyboardIdentifierS1__PSs9AnyObject_ + 79
12 CoreFoundation 0x000000010acfe85c __invoking___ + 140
13 CoreFoundation 0x000000010acfe6ae -[NSInvocation invoke] + 286
14 CoreFoundation 0x000000010ad8f016 -[NSInvocation invokeWithTarget:] + 54
15 MyApp 0x000000010520ea76 objc_msgSend_InjectionArguments + 454
16 MyApp 0x000000010520e83e -[TyphoonAssemblyDefinitionBuilder definitionForKey:] + 254
17 MyApp 0x000000010520e61f -[TyphoonAssemblyDefinitionBuilder populateCacheWithDefinitionForKey:] + 111
18 MyApp 0x000000010520e01b -[TyphoonAssemblyDefinitionBuilder builtDefinitionForKey:args:] + 203
19 MyApp 0x000000010520df20 -[TyphoonAssemblyDefinitionBuilder buildDefinitionForKey:] + 64
20 MyApp 0x000000010520de43 __49-[TyphoonAssemblyDefinitionBuilder populateCache]_block_invoke + 163
21 CoreFoundation 0x000000010ad6f0df __51-[__NSSetM enumerateObjectsWithOptions:usingBlock:]_block_invoke + 79
22 CoreFoundation 0x000000010ad6efea -[__NSSetM enumerateObjectsWithOptions:usingBlock:] + 202
23 MyApp 0x000000010520dd69 -[TyphoonAssemblyDefinitionBuilder populateCache] + 185
24 MyApp 0x000000010520dc1a -[TyphoonAssemblyDefinitionBuilder builtDefinitions] + 74
25 MyApp 0x000000010520a976 -[TyphoonAssembly definitions] + 54
26 MyApp 0x000000010520ff1a -[TyphoonBlockComponentFactory registerAllDefinitions:] + 90
27 MyApp 0x000000010520fd78 -[TyphoonBlockComponentFactory buildAssembly:] + 104
28 MyApp 0x000000010520fc10 -[TyphoonBlockComponentFactory initWithAssemblies:] + 544
29 MyApp 0x000000010520f8b7 +[TyphoonBlockComponentFactory factoryWithAssemblies:] + 87
30 MyApp 0x00000001052340d2 +[TyphoonStartup requireInitialFactory] + 194
31 MyApp 0x00000001052345ad __60+[TyphoonStartup swizzleSetDelegateMethodOnApplicationClass]_block_invoke + 93
32 UIKit 0x0000000108a8825b -[UIApplication _setDelegate:assumeOwnership:] + 51
33 UIKit 0x0000000108a93cea _UIApplicationMainPreparations + 1618
34 UIKit 0x0000000108a93647 UIApplicationMain + 124
35 MyApp 0x0000000104b1f80f main + 111
36 libdyld.dylib 0x000000010c5a492d start + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException
1 ответ
Typhoon - это довольно типичный контейнер для интроспективного и отражающего типа, оптимизированный для Objective-C. (Также хорошо работает для Swift).
- При запуске: Typhoon собирает информацию со всех сборок о том, как строить объекты
- Во время выполнения: интерфейс сборки находится перед TyphoonComponentFactory, который знает, как создавать компоненты на основе всех этих собранных правил.
Чтобы получить компонент:
Rules parsed on startup->post processing->factory emits built objects
Поэтому: в случае аргументов времени выполнения мы не можем вызывать какие-либо методы для них или иным образом манипулировать ими после их передачи, потому что это не будет иметь отношения к фазе запуска, когда Typhoon создает чертежи экземпляров объекта.
Если вы объявляете аргумент времени выполнения типа NSString и передаете его напрямую без манипуляций (вместо NSString(string: storyboardIdentifier)
), должно работать нормально.