¿Cómo uso CFArrayRef en Swift?

Estoy usando una class Objective-C en mi proyecto Swift a través de un encabezado de puente. La firma del método se ve algo como esto:

- (CFArrayRef)someMethod:(someType)someParameter; 

Empecé obteniendo una instancia de la class, llamando al método y almacenando el valor:

 var myInstance = MyClassWithThatMethod(); var cfArr = myInstance.someMethod(someValue); 

Luego intente get un valor en la matriz:

 var valueInArrayThatIWant = CFArrayGetValueAtIndex(cfArr, 0); 

Sin embargo, obtengo el error Unmanaged<CFArray>' is not identical to 'CFArray' . ¿Qué quiere decir Unmanaged<CFArray> ?

Miré a través de Cómo convertir CFArray a Swift Array? pero no necesito convertir la matriz a una matriz rápida (sin embargo, sería agradable). Solo necesito poder get valores de la matriz.

También he probado el método de pasar el CFArray a una function descrita en esta respuesta :

 func doSomeStuffOnArray(myArray: NSArray) { } 

Sin embargo, recibo un error similar al usarlo:

 doSomeStuffOnArray(cfArr); // Unmanaged<CFArray>' is not identical to 'NSArray' 

Estoy usando CFArray porque necesito almacenar una matriz de CGPathRef , que no se puede almacenar en NSArray .

Entonces, ¿cómo se supone que debo usar CFArray en Swift?

Como se explica en Trabajar con types de datos de cocoa , hay dos soluciones posibles cuando devuelve un object Core Foundation de su propia function que se importa en Swift:

  • CF_RETURNS_RETAINED la function con CF_RETURNS_RETAINED o CF_RETURNS_NOT_RETAINED . En tu caso:

     - (CFArrayRef)someMethod:(someType)someParameter CF_RETURNS_NOT_RETAINED; 
  • O convierta el object no administrado en un object gestionado de memory con takeUnretainedValue() o takeRetainedValue() en Swift. En tu caso:

     var cfArr = myInstance.someMethod(someValue).takeUnretainedValue() 

Un no Unmanaged es un contenedor para un valor de CF real. (Una especie de como opcional.) Está allí porque ARC no puede decir de mirar la statement de someMethod: si ese método conserva el valor que devuelve.

Usted desenvuelve un No Unmanaged diciéndole a ARC qué política de administración de memory usar para el valor dentro. Si someMethod llama a CFRetain en su valor devuelto:

 let cfArr = myInstance.someMethod(someValue).takeRetainedValue() 

Si no lo hace:

 let cfArr = myInstance.someMethod(someValue).takeUnretainedValue() 

Después de hacer eso, cfArr es un CFArray , por lo que puede utilizar los trucos de puente de las otras preguntas a las que se ha vinculado para acceder a él como una matriz Swift.

Si posee el código de someMethod , puede cambiarlo un poco para que no lo necesite. Hay un par de opciones para eso:

  • CF_RETURNS_RETAINED con CF_RETURNS_RETAINED o CF_RETURNS_NOT_RETAINED para decirle al comstackdor qué comportamiento de memory se necesita
  • Dado que es un método ObjC, puentee a NSArray y devuelva eso, se convertirá automáticamente en una matriz [AnyObject] en Swift.