objective-c cocoa automatic-ref-counting objective-c-blocks weak-references

objective c - Tipo genérico para auto referencias débiles



objective-c cocoa (10)

Referencia de Weakself genérica (no se requiere importación + fragmento)

En mi experiencia, el camino a seguir es usar:

__typeof__(self) __weak weakSelf = self;

Observe cómo el calificador de propiedad pertenece al frente de la variable real.

Es muy evidente lo que sucede cuando se usa y se puede convertir en un práctico fragmento de código en Xcode, lo que hace que sea aún más fácil de usar en cualquier proyecto o clase donde sea necesario. (Uso "ws" como atajo de finalización del fragmento)

Hmm ... Necesito una referencia débil aquí ...

ws{return}

Hecho. No es necesario incluir un encabezado en futuros proyectos para esto, solo use el fragmento.

Fragmento de Xcode

Título: Generic Weak Self Reference
Plataforma: All
Idioma: Objective-C
Atajo de finalización: ws
Alcance de finalización: Function or Method
Código: __typeof__(self) __weak weakSelf = self;

Editar: se agregó una nota sobre la posición del calificador de propiedad en función de los comments , y Xcode Snippet Info

Estoy tratando de encontrar una manera de usar typeof para crear una referencia débil a self para usar en bloques para evitar retener ciclos.

Cuando leí por primera vez acerca de esto, parece que la convención era usar __block typeof(self) bself = self; , que compila pero usa __block para evitar retener ciclos ya no funciona y __weak debería usarse en su lugar.

Sin embargo, __weak typeof(self) bself = self; resulta en un error:

El tipo ''typeof (self)'' (también conocido como ''TUAccountsViewController * const __strong'') ya tiene atributos de retención establecidos

¿Hay alguna manera de usar typeof u otra llamada para crear genéricamente una referencia débil a self ?


¡Esto funciona!

__typeof__(o) __weak

Que he definido en mi proyecto de BBlockWeakSelf como BBlockWeakSelf que se puede usar así:

BBlockWeakSelf wself = self;

https://github.com/kgn/BBlock/blob/master/BBlock.h

Editado basado en la respuesta de Aleph7.


¿Por qué no solo usas

__weak id bself = self;


¿Qué hay de __unsafe_unretained? Eso no es tan seguro como __weak, pero es lo único que se me ocurre. Además, ¿por qué usas typeof ()?


Creo que usa esto para estar bien:

__weak __typeof (& * self) weakSelf = self;

hace referencia a los códigos AFURLConnectionOperation.m de AFNetworking.


En la última versión clang Apple clang versión 4.0 (etiquetas / Apple / clang-421.1.48) (basado en LLVM 3.1svn) , es decir Xcode 4.4+ , el __typeof__((__typeof__(self))self) no es necesario más. El tipo __weak typeof(self) bself = self; la línea compilará muy bien.


La forma correcta de hacerlo es

__weak ActualClassName* weakSelf = self;

Las macros solo dejan en claro cuál es la variable en realidad, y qué es lo que realmente está haciendo con ella, además de agregar metalenguaje no portátil a su código.

Si necesita una versión más genérica de la clase de la que proporciona ActualClassName, ya no se trata de self , ya que cuando se define self , también lo es la clase de self .

En esos casos, debe usar el nombre de clase base más cercano en su árbol de herencia, NSObject o mejor, nunca id , por ej.

__weak MyBaseClassName* weakObject = object;


Tengo esta macro

#define weaken(object) __typeof__(self) __weak weakSelf = object

Y lo uso así

weaken(self); //The block referencing weakSelf goes here


Tuve un error similar pero lo solucioné de manera diferente:

Fui a Project Navigator -> Project -> Target -> Build Settings

Ahí busqué C Language Dialect. Lo cambié de c11 a GNU99 y resolvió mi problema.

Espero que ayude :)


declareBlockSafe (self) luego blk (self) dentro del bloque. El yo puede ser cualquier variable o variable de instancia. Utilice declareBlockSafeAs para las propiedades y los retornos de métodos.

También funciona con no ARC si importa el espléndido MAZeroingWeakRef de Mike Ash. https://github.com/mikeash/MAZeroingWeakRef

#if __has_feature(objc_arc)

#define declareBlockSafe(__obj__) __weak typeof(__obj__) __tmpblk##__obj__ = __obj__ #define blockSafe(__obj__) __tmpblk##__obj__ #define blk(__obj__) blockSafe(__obj__) #define declareBlockSafeAs(__obj__, __name__) / __weak typeof((__obj__)) __tmpblk##__name__ = (__obj__) #else #define declareBlockSafe(__obj__) MAZeroingWeakRef *__tmpblk##__obj__ = [MAZeroingWeakRef refWithTarget:__obj__] #define blockSafe(__obj__) ((typeof(__obj__))__tmpblk##__obj__##.target) #define blk(__obj__) blockSafe(__obj__) #define declareBlockSafeAs(__obj__, __name__) / MAZeroingWeakRef *__tmpblk##__name__ = (__obj__) #endif

REALMENTE no necesita blk () para ARC, es solo para que las macros se puedan usar de la misma manera para las que no sean ARC.