Ваше закрытие не является блоком Objective-C, поэтому оно не может быть передано через среду выполнения ObjC. Вы должны пометить его как блок, используя @convention
.
let closure: @convention(block) () -> Void = { ... }
Вы можете преобразовать существующее замыкание в блок, назначив его:
let closure = { ... }
let block: @convention(block) () -> Void = closure
perform(#selector(foo(param:)), with: block)
Блоки Objective-C фактически являются объектами и участвуют в ARC. Сбой происходит из-за того, что perform
пытается вызвать Block_copy
для неблокированного блока.
Конечно, как правило, селекторы не являются подходящими инструментами в Swift, и вы должны преобразовать любой интерфейс на основе селектора, чтобы он просто взял аргумент функции. Если вы обнаружите, что используете perform
, вы, вероятно, не в ту сторону в Swift. Но он все еще доступен, если вам это нужно.