У меня есть смешанный проект ObjC и Swift iOS.
У меня есть класс для тестирования внедрения тривиального закрытия во время выполнения:
@objc
class TyphoonClosureTester: NSObject {
@objc var closure: (() -> Void)?
@objc
override init() {}
@objc
init(closure: (() -> Void)?) {
self.closure = closure
}
@objc
func callClosure() {
guard let closure = closure else {
assert(false, "no closure 1")
return
}
closure()
NSLog("Have called closure 1 OK")
}
}
Мой файл сборки для Тайфуна содержит эту функцию:
func testAClosure(closure: @escaping () -> Void) -> AnyObject {
return TyphoonDefinition.withClass(TyphoonClosureTester.self) { definition in
definition?.useInitializer(#selector(TyphoonClosureTester.init(closure:))) { initializer in
initializer?.injectParameter(with: closure)
}
definition?.scope = .prototype
} as AnyObject
}
И я пытаюсь использовать это закрытие следующим образом:
let closureTester1: TyphoonClosureTester = assembler.testAClosure(closure: {
NSLog(" closure 1 called!")
}) as! TyphoonClosureTester
// causes EXC_BAD_ACCESS
closureTester1.callClosure()
но это приводит к EXC_BAD_ACCESS
, когда я вызываю закрытие. (Точное сообщение: Thread 1: EXC_BAD_ACCESS (code=1, address=0x0)
) Похоже, замыкание где-то освобождается.
Я пытался добавить захват в сборку (т.е. [closure]
), но это не имеет значения:
func testAClosure(closure: @escaping () -> Void) -> AnyObject {
return TyphoonDefinition.withClass(TyphoonClosureTester.self) { [closure] definition in
definition?.useInitializer(#selector(TyphoonClosureTester.init(closure:))) { [closure] initializer in
initializer?.injectParameter(with: closure)
}
definition?.scope = .prototype
} as AnyObject
}
Я также попытался внедрить закрытие как свойство, а не через init, и это не имело никакого значения.