/ / Преобразуване на Swift 2 затваряне към обект-C блок - цел-c, swift2, затваряне, обективи-c-блокове

Конвертиране на Swift 2 затваряне на обект-C блок - цел-c, swift2, затваряне, обективи-c-блокове

Опитвам се да изградя обект-C блок в Swift 2, за да го добавим към NSArray така :

typealias CompletionBlock = () -> Void
let aBlock:CompletionBlock =  {
print("Hello world!")
}
let nsArray = NSMutableArray()
nsArray.addObject(aBlock) // Error

Знам, че ще работи добре с масив Swift, но имам нужда от него NSArray тук за съвместимост със съществуващия код на Цел-С. И ако използвам бърз масив, съставителят ще откаже да го хвърли на един NSArray защото няма да бъде [AnyObject] (това ще бъде [Any]).

Проблемът тук е, че бързото затваряне не е обект, противоречащ на блоковете на Цел-С, които са обекти зад сцената (те са случаи на NSBlock който е подклас на NSObject)

Така че въпросът ми е: Как да създадете обект-C блок в бърз? Опитах да използвам @convention (block) в типията, но тя не работи.

Отговори:

6 за отговор № 1

РЕДАКТИРАНЕ : От Swift 3, това е напълно ненужно (и дори не работи). Добавянето на затваряне към обектите на Цел-С работи извън кутията в Swift 3. Отговорът по-долу е валиден само за Swift 2.

Знам, че това е дубликат, но все пак ще публикувам отзивчив отговор бързо затваряне, както-anyobject и чугунени калодки затваряне в случай че първо се качи на някого.

Решението е да се използва unsafeBitCast функция за преобразуване на затварянето на Swift в съвместим с Objective-C обект, преди да го добавите към NSArray и преди да го използвате в Swift.

// The `@convention(block)` is important here in order to get
// Objective-C like memory management
typealias CompletionBlock = @convention(block) () -> Void

let aBlock:CompletionBlock = {
print("Hello world!")
}
let nsArray = NSMutableArray()
let blockObject = unsafeBitCast(aBlock, AnyObject.self)
nsArray.addObject(blockObject)

let closureObject = nsArray[0]
let closure = unsafeBitCast(closureObject, CompletionBlock.self)
closure()