2015-10-05 5 views
27

Hier ist der Code:Wert des Typs 'Meme!' Kann nicht konvertiert werden zu erwarteten Argumenttyp '@noescape (Meme) throws -> 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) 

Der Fehler bei den .indexOf Verfahren bei (selectedMeme) passiert.

Wert kann nicht vom Typ Meme! zu erwarteten Argumenttyp @noescape (Meme) throws -> Bool

Meme konvertieren! ist eine Struktur für meine App. Wie arbeite ich das durch?

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 

Antwort

44

Die Fehlermeldung ist irreführend. Was Sie tatsächlich brauchen, ist, dem Compiler eine Möglichkeit zu geben, zwei Meme Instanzen zu vergleichen und zu entscheiden, nach welchen Kriterien diese Instanzen gleich sind.

Angenommen, Sie möchten, dass zwei Instanzen dieselbe name-Eigenschaft haben, die als gleich behandelt wird.

Wir machen die Struktur zu Equatable entsprechen und wir auch einen == Operator erstellen, die zwei Strukturen durch ihren Namen Eigenschaft vergleicht:

struct Meme:Equatable { 
    var name:String! 
} 

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

Jetzt können wir indexOf mit einer Meme-Instanz verwenden:

let doge = Meme(name: "doge") 

let lolcat = Meme(name: "lolcat") 

let memes = [lolcat, doge] 

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

Wenn Sie zwei Instanzen nicht nach ihrer name Eigenschaft, sondern nach ihrer Eindeutigkeit vergleichen möchten, müssten Sie die Struktur an Hashable anpassen und eine eindeutigeverwendenEigenschaft Rückkehr eine 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 diesem Beispiel wird die hashValue von self.name hergestellt ist, so dass zwei verschiedene Instanzen von Meme mit einer gleichnamigen Eigenschaft wird gleich betrachtet werden. Wenn Sie das nicht möchten, verwenden Sie eine andere Quelle für den Hash-Wert.

Hinweis: in Swift 3 hat indexOfindex(of:) geworden, so in diesem Beispiel wir memes.indexOf(doge) zu ändern würde.

+2

Danke. Hatte eine harte Zeit versucht, das zu lösen. – nahwarang

+1

Perfekte Antwort. Aber warum ist das noch nicht akzeptiert? – BLC

+0

@BLC 2017 und es wurde immer noch nicht akzeptiert –

5

Wenn Sie den Vergleich innerhalb der indexOf Methode setzen wollen selbst, tun es wie folgt aus:

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

wahrscheinlich nicht der beste Weg, um Bilder zu vergleichen. Wenn Sie die Bilder sind das gleiche Objekt kennen, können Sie verwenden:

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

aber wenn man sie Pixel für Pixel oder vergleichen das gleiche Bild skaliert, um verschiedene Größen vergleichen wollen, das ist ein wenig komplizierter.

+0

Vielen Dank für Ihre Hilfe. Ich schätze die Zeit und Mühe. Hier ist mein Projekt, wenn Sie es überprüfen möchten: https://github.com/pbellot77/MemeMe.git –