Литые крышки / блоки

В Objective-C я часто раздаю блоки. Я использую их очень часто для реализации шаблонов, которые помогают избежать хранения вещей в переменных экземпляра, тем самым избегая проблем с потоками / синхронизацией.

Например, я назначаю ихCAAnimation с помощью-[CAAnimation setValue:forKey:] так что я могу выполнить блок, когда анимация закончена. (Objective-C может обрабатывать блоки как объекты; вы также можете сделать[someBlock copy] а также[someBlock release].)

Однако попытка использовать эти шаблоны в Swift вместе с Objective-C кажется очень сложной. (Редактировать: и мы можем видеть, что язык все еще в движении: адаптировали код, чтобы он работал на Xcode6-beta2, предыдущая версия работала на Xcode6-beta1.)

Например, я не могу конвертироватьAnyObject Вернуться к блоку / закрытию. Следующее приводит к ошибке от компилятора:

override func animationDidStop(anim: CAAnimation!, finished flag: Bool)
{
    let completion : AnyObject! = anim.valueForKey("completionClosure")
    (completion as (@objc_block ()->Void))()
    // Cannot convert the expression's type 'Void' to type '@objc_block () -> Void'
}

Я нашел обходной путь, но это довольно уродливо, ИМХО: в моем соединительном заголовке у меня есть:

static inline id blockToObject(void(^block)())
{
    return block;
}

static inline void callBlockAsObject(id block)
{
    ((void(^)())block)();
}

И теперь я могу сделать это в Swift:

func someFunc(completion: (@objc_block ()->Void))
{
    let animation = CAKeyframeAnimation(keyPath: "position")
    animation.delegate = self
    animation.setValue(blockToObject(completion), forKey: "completionClosure")
    …
}

override func animationDidStop(anim: CAAnimation!, finished flag: Bool)
{
    let completion : AnyObject! = anim.valueForKey("completionClosure")
    callBlockAsObject(completion)
}

Это работает, но мне нужна новая функция для каждого типа блока, который я хотел бы использовать, и я хакиваю компилятор, который тоже не может быть хорошим.

Так есть ли способ решить это чисто Swift?

Ответы на вопрос(4)

Ваш ответ на вопрос