web-dev-qa-db-fra.com

Impossible de convertir la valeur de type "Meme!" au type d'argument attendu '@noescape (Meme) lance -> Bool'

Voici le code:

    @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'erreur se produit à la méthode .indexOf À (selectedMeme).

Impossible de convertir la valeur de type Meme! En type d'argument attendu @noescape (Meme) throws -> Bool

Meme! est une structure pour mon application. Comment puis-je résoudre ce problème?

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
27
Patrick.Bellot

Le message d'erreur est trompeur. Ce dont vous avez réellement besoin est de fournir au compilateur un moyen de comparer deux instances de Meme et de décider sur quels critères ces instances sont égales.

Supposons que vous souhaitiez que deux instances ayant la même propriété name soient traitées comme égales.

Nous rendons la structure conforme à Equatable et nous créons également un opérateur == Qui compare deux structures par leur propriété de nom:

struct Meme:Equatable {
    var name:String!
}

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

Maintenant, nous pouvons utiliser indexOf avec une instance Meme:

let doge = Meme(name: "doge")

let lolcat = Meme(name: "lolcat")

let memes = [lolcat, doge]

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

Si vous vouliez comparer deux instances non pas par leur propriété name mais par leur unicité, alors vous devriez rendre la structure conforme à Hashable et utiliser une propriété hashValue unique renvoyant 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
}

Dans cet exemple, le hashValue est fait de self.name, Donc deux instances différentes de Meme avec une même propriété de nom seront considérées comme égales. Si vous ne le souhaitez pas, utilisez une autre source pour la valeur de hachage.

Remarque: dans Swift 3, indexOf est devenu index(of:), donc pour cet exemple, nous changerions memes.indexOf(doge) en memes.index(of: doge).

44
ayaio

Si vous souhaitez placer la comparaison dans la méthode indexOf elle-même, faites-le comme ceci:

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

Probablement pas la meilleure façon de comparer des images. Si vous savez que les images sont le même objet, vous pouvez utiliser:

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

mais si vous voulez les comparer pixel par pixel ou comparer la même image à différentes tailles, c'est un peu plus compliqué.

5
Millie H.