EXC_BAD_ACCESS при внедрении замыкания во время выполнения с помощью Typhoon

У меня есть смешанный проект 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, и это не имело никакого значения.


person occulus    schedule 01.05.2019    source источник


Ответы (1)


По памяти это не поддерживается. Вы можете попробовать поискать в тестовых примерах пример.

Внедрение обернутых примитивов описано здесь: https://github.com/appsquickly/typhoon/wiki/wrap-primitive-values-into-NSValue

. . однако нет ссылки на блоки/замыкания.

Если вы описываете, чего хотели бы достичь, может быть предложен следующий лучший обходной путь.

person Jasper Blues    schedule 01.05.2019
comment
Спасибо. Да, я знал, что нужна примитивная упаковка, но нигде не нашел ничего, что говорило бы о том, что не используйте замыкания/блоки - было бы интересно найти это. Я думаю, что вы можете быть правы, хотя! - person occulus; 01.05.2019
comment
Я думаю, что это действительно не поддерживается! извините за большую задержку с принятием вашего ответа. - person occulus; 17.01.2020