objective swift

objective c to swift



El elemento de matriz no se puede unir a Objective-C (5)

Con las matrices Swift, puede llamar a bridgeToObjectiveC() en ellas y se convertirán en NSArrays. Lo mismo es cierto para los diccionarios Swift.

Tengo este código que crea una vista y le aplica un degradado.

import UIKit import QuartzCore let rect : CGRect = CGRectMake(0,0,320,100) var vista : UIView = UIView(frame: rect) let gradient : CAGradientLayer = CAGradientLayer() gradient.frame = vista.bounds let cor1 = UIColor.blackColor() let cor2 = UIColor.whiteColor() let arrayColors = [cor1.CGColor, cor2.CGColor] gradient.colors = arrayColors view.layer.insertSublayer(gradient, atIndex:0)

Xcode no me da ningún error de compilación, pero el código se bloquea en la línea

let arrayColors = [cor1.CGColor, cor2.CGColor]

con el elemento de matriz de mensajes no se puede unir a Objective-C

De hecho, esperaba que se bloqueara allí, porque no estoy seguro de cómo puedo crear una matriz de CGColors en Swift. La sorpresa aquí es que Xcode menciona Objective-C. En mi mente, estaba creando un CGColorRef a toda velocidad ...

¿Alguna pista? ¿Por qué está mencionando Objective-C y cómo lo resuelvo?


Descubrí que podía solucionar el problema usando explícitamente CGColorRef en lugar de CGColor para mis colores, por ejemplo:

var bottomColour:CGColorRef = UIColor.redColor().CGColor var topColour:CGColorRef = UIColor(red: 255.0/255.0, green: 123.0/255.0, blue: 37.0/255.0, alpha: 1.0).CGColor gradientLayer.colors = [bottomColour, topColour]

... funcionó bien, sin ningún casting NSArray o AnyObject. Si elimino el CGColorRef explícito en las declaraciones de tipo para los colores, aparece el error "el elemento de la matriz no puede enlazarse al Objective-C".


Este error de tiempo de ejecución también puede activarse si intenta tender un puente entre una matriz de tipo [MySwiftProtocol] y Objective-C.

La solución es marcar su protocolo con @objc :

@objc protocol MySwiftProtocol { // ... }


La razón por la cual se menciona Objective-C es porque UIKit y QuartzCore son marcos Objective-C. En particular, gradient.colors = arrayColors llama a un método Objective-C que espera un NSArray .

Esto parece un error, ya que la documentación de Apple hace que parezca que la matriz debe puentear automáticamente a un NSArray siempre que los elementos en la matriz se puedan considerar AnyObject :

Cuando pasa de una matriz Swift a un objeto NSArray, los elementos de la matriz Swift deben ser compatibles con AnyObject. Por ejemplo, una matriz Swift de tipo Int [] contiene elementos de estructura Int. El tipo Int no es una instancia de una clase, sino porque el tipo Int se une a la clase NSNumber, el tipo Int es compatible con AnyObject. Por lo tanto, puede puentear una matriz Swift de tipo Int [] a un objeto NSArray. Si un elemento de una matriz Swift no es compatible con AnyObject, se produce un error en el tiempo de ejecución cuando realiza un enlace a un objeto NSArray.

También puede crear un objeto NSArray directamente desde un literal de matriz Swift, siguiendo las mismas reglas de puente descritas anteriormente. Cuando escribe explícitamente una constante o variable como un objeto NSArray y le asigna un literal de matriz, Swift crea un objeto NSArray en lugar de una matriz Swift.

Por ahora, una arrayColors sería declarar arrayColors como un NSArray :

let arrayColors: NSArray = [cor1.CGColor, cor2.CGColor]

O para declarar que toma AnyObject :

let arrayColors: Array <AnyObject> = [cor1.CGColor, cor2.CGColor]


Para cualquiera que intente hacer que esto funcione en Swift, puede hacer lo siguiente:

let arrayColors: NSArray = [UIColor.blackColor().CGColor as AnyObject, UIColor.clearColor().CGColor as AnyObject]

Noté que en mi código Objective-C estaba transfiriendo los tipos CGColorRef a id. Sin embargo, no estoy seguro de por qué. Si alguien tiene una razón por la que sería genial!