6

Estoy escribiendo código destinado a funcionar tanto bajo ARC como en Garbage Collection.Puente ARC/GC de Dual Mode y Core Foundation

Aquí hay un poco de código que utiliza base fundamental, ya que podría ser escrito específicamente para ARC:

CFTypeRef ref=CFCopySomething(); 
// At this point ref has retain count 1. 
id obj=(__bridge_transfer id)ref; 
// Ref still has retain count 1 but is now managed by ARC. 
[obj doSomething]; 
// ARC will release ref when done. 

Parece que esto es equivalente a:

CFTypeRef ref=CFCopySomething(); 
// At this point ref has retain count 1. 
id obj=(__bridge id)ref; 
// Now ref has retain count 2 due to assigning to strong variable under ARC. 
CFRelease(ref) 
// Now ref has retain count 1. 
[obj doSomething]; 
// ARC will release ref when done. 

El beneficio de este último que la llamada CFRelease permite que el GC recoja el objeto. Pero no estoy seguro de llamar al CFRelease después de transferirlo a ARC con la asignación de bridge-casted.

Parece que funciona. ¿Está bien este código?

+1

Vale la pena mencionar a los lectores que los títulos '__bridge' no tienen ningún significado en las unidades de compilación que no son ARC, es decir, el compilador simplemente los ignorará al compilar con' -objc-gc', haciendo que su segundo fragmento de código sea compatible tanto ARC como GC. (Solo digo eso porque tuve que buscar) – paulotorrens

Respuesta

2

Su segundo fragmento de código es correcto, y de hecho es la mejor manera de manejar tanto el ARC y GC. También es posible usar CFMakeCollectable al crear el objeto, y luego tener la CFRelease realiza de la siguiente manera:

si ([NSGarbageCollector defaultCollector] == NULL) CFRelease (myCFString)

Pero me gusta más lo que tienes con solo una llamada que funciona para ambos entornos.

1

Nick,

Como los CFObjects no se manejan por ARC, que en realidad puede que desee mantener el código administrado manualmente aquí. ARC está realmente enfocado en Cocoa y no en Core Foundation. Dicho esto, dijiste que el código funciona pero ¿se filtra? Recuerde que el código ARC con los indicadores del compilador incorrectos falla al tener fugas. En esta documentación de Apple, afirman que ARC no gestiona objetos CF: https://developer.apple.com/library/ios/#releasenotes/ObjectiveC/RN-TransitioningToARC/Introduction/Introduction.html. Por lo tanto, creo que su código __bridge se filtra y espera su confirmación o rechazo de la herramienta de fugas de Instruments.

Andrew

+1

Puedo confirmar que el código no se filtra cuando se compila bajo ARC. –

+0

Nick, está bien, me alegro de que hayas confirmado eso. Para su pregunta de GC, ya que su CFRelease puede ocurrir en cualquier lugar después de su último uso, ¿por qué lo está colocando antes de su último uso y esperando que ARC/GC lo resuelva? Si solo se apega al patrón estándar para objetos CF, entonces no tiene que pensar en los problemas ARC v GC. IOW, en su segundo bloque, mueva la CFRelease al último punto que necesite el artículo. Ni ARC ni GC serán mucho más inteligentes al respecto que tú. (Por cierto, creo que su asignación de puente no hace más que cambiar el nombre. No se modifican las semánticas de asignación.) Andrew – adonoho

+1

Según el CG, se requiere CFRelease para marcar un objeto CF como objeto de colección. Es convencional hacer esto en el momento de la creación (a menudo usando CF/NSMakeCollectable, pero CFRelease funciona igual de bien). Del mismo modo, con ARC quiero entregar el objeto a ARC lo antes posible. Todo realmente funciona. –