Swift ARC y bloques

Estoy probando un ejemplo simple como se ve aquí: https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_Language/AutomaticReferenceCounting.html#//apple_ref/doc/uid/TP40014097-CH20 -XID_88

Y este es mi código. (Ignore otro código posible, este es un proyecto vacío con este código escrito dentro de una vista vacía de UIViewcontrollerDidLoad)

dispatch_async(dispatch_get_main_queue()) { [unowned self] in println(self) } 

No entiendo por qué se bloquea cuando ejecuto el pro

  • hilo # 1: tid = 0x1a796, 0x00284d18 libswiftCore.dylib`_swift_release_slow + 8, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (código = 1, dirección = 0x458bc681)

¿Ha cambiado algo en la versión beta más reciente (5) y ya no es compatible? Gracias

editar: Interesante que este código funcione en Objc

 __weak MyViewController *weakSelf = self; dispatch_async(dispatch_get_main_queue(), ^{ NSLog(@"%@", weakSelf); }); 

edit2: La explicación en este enlace: ¿Siempre usaremos [el ser no propietario] dentro del cierre en Swift sobre la diferencia entre débil y no propietario es incorrecto.

No es solo que los débiles y no propietarios no. Si ese es el caso, esto también debería fallar:

  dispatch_async(dispatch_get_main_queue()) { [weak self] in println(self) } 

pero no funciona, e imprime el puntero, por lo tanto, no es nulo.

[Unowned self] hace así que el cierre no crea una fuerte reference a self y no lo pone automáticamente a nil si también se desasigna. Para cuando se ejecuta el método asynchronous, el self se ha desasignado. Es por eso que está sufriendo el crash.

Ciertamente, no tiene sentido usar unowned en una llamada asíncrona de una sola vez. Sería mejor capturar una reference fuerte para asegurarse de que se adhiera. Todavía no habrá un ciclo de reference fuerte porque self mismo no posee el cierre.

Nota lateral: Esto no puede ser todo su código como self no está definido en ningún lugar de su código.

unowned y weak son dos cosas diferentes. En Objective-C, unowned se denomina unsafe unretained . Puede usar weak en ambos idiomas. weak significa que el time de ejecución convertirá automáticamente la reference a nil si el object se desasigna. unowned unsafe unretained o unowned unsafe unretained significa que no se establecerá en nil para usted (por lo que se denomina "inseguro" en Objective-C.

Unowned solo se debe usar en circunstancias donde el object nunca será desasignado. En esas circunstancias, use weak .

Tenga en count que si captura una variable como weak en Swift, la reference se convertirá en una opción, por lo tanto, para usarla, tendrá que desenvolverla:

 dispatch_async(dispatch_get_main_queue()) { [weak self] in if let actualSelf == self { // do something with actualSelf } // you can still print the "wrapped" self because it is fine to print optionals // even if they are `nil` println(self) } 

Pero para que quede claro, sería mejor utilizar una fuerte reference en esta circunstancia:

 dispatch_async(dispatch_get_main_queue()) { println(self) }