2015-10-05 12 views
27

Ecco il codice:Impossibile convertire il valore di tipo 'Meme!' al tipo di argomento atteso '@noescape (Meme) getta -> Bool'

@IBAction func deleteMeme(sender: UIBarButtonItem) { 
     if let foundIndex = MemeRepository.sharedInstance.memes.indexOf(selectedMeme) {  
     //remove the item at the found index 
     MemeRepository.sharedInstance.memes.removeAtIndex(foundIndex) 
     navigationController?.popViewControllerAnimated(true) 

L'errore avviene al metodo di .indexOf a (selectedMeme).

Non può convertire il valore di tipo Meme! al previsto tipo di argomento @noescape (Meme) throws -> Bool

Meme! è una struct per la mia app. Come lavoro attraverso questo?

struct Meme { 

var topText : String! 
var bottomText: String! 
var image: UIImage! 
var memedImage: UIImage! 

init(topText: String, bottomText: String, image: UIImage, memedImage: UIImage) { 
    self.topText = topText 
    self.bottomText = bottomText 
    self.image = image 
    self.memedImage = memedImage 

risposta

44

Il messaggio di errore è fuorviante. Ciò che è effettivamente necessario è fornire al compilatore un modo per confrontare due istanze Meme e decidere in base a quali criteri queste istanze sono uguali.

Supponiamo che due istanze con la stessa proprietà name siano trattate come uguali.

Facciamo lo struct conforme alle Equatable e abbiamo anche creare un == operatore che mette a confronto due le strutture per le loro proprietà nome:

struct Meme:Equatable { 
    var name:String! 
} 

func ==(lhs: Meme, rhs: Meme) -> Bool { 
    return lhs.name == rhs.name 
} 

Ora possiamo usare indexOf con un'istanza Meme:

let doge = Meme(name: "doge") 

let lolcat = Meme(name: "lolcat") 

let memes = [lolcat, doge] 

if let dogeIndex = memes.indexOf(doge) { 
    print(dogeIndex) // 1 
} 

Se si desidera confrontare due istanze non dalla loro proprietà name ma dalla loro univocità, quindi si dovrebbe rendere la struttura conforme a Hashable e utilizzare ununivocostruttura restituire un Int:

struct Meme:Hashable { 
    var name:String! 
    var hashValue: Int { 
     return self.name.hashValue 
    } 
    init(name: String) { 
     self.name = name 
    } 
} 

func ==(lhs: Meme, rhs: Meme) -> Bool { 
    return lhs.hashValue == rhs.hashValue 
} 

let doge = Meme(name: "doge") 

let lolcat = Meme(name: "lolcat") 

let memes = [lolcat, doge] 

if let dogeIndex = memes.indexOf(doge) { 
    print(dogeIndex) // 1 
} 

In questo esempio il hashValue è costituito da self.name, quindi due istanze diverse di Meme con una stessa proprietà nome vengono considerati uguali. Se non lo vuoi, usa un'altra fonte per il valore hash.

Nota: in 3 Swift, indexOf è diventato index(of:), quindi per questo esempio che vorremmo cambiare memes.indexOf(doge) a .

+2

Grazie. Ha avuto difficoltà a cercare di risolvere questo. – nahwarang

+1

Risposta perfetta. Ma perché questo non è ancora accettato? – BLC

+0

@ BLC 2017 e ancora non è stato accettato –

5

Se si desidera mettere il confronto all'interno del metodo indexOf stesso, fare in questo modo:

if let foundIndex = MemeRepository.sharedInstance.memes.indexOf({ 
    UIImagePNGRepresentation($0.memedImage) == UIImagePNGRepresentation(selectedMeme.memedImage)}) 

Probabilmente non è il modo migliore per confrontare le immagini. Se conoscete le immagini sono lo stesso oggetto, è possibile utilizzare:

.indexOf({$0.memedImage == selectedMeme.memedImage}) 

ma se volete confrontarli pixel per pixel o confrontare la stessa immagine in scala di diverse dimensioni, che è un po 'più complicato.

+0

Grazie a tutti per il vostro contributo e aiuto. Apprezzo il tempo e lo sforzo. Ecco il mio progetto se vuoi verificarlo: https://github.com/pbellot77/MemeMe.git –

Problemi correlati