Подтвердить что ты не робот

Невозможно преобразовать значение типа "Meme!" к ожидаемому типу аргументов '@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)

Ошибка происходит при методе .indexOf в (selectedMeme).

Невозможно преобразовать значение типа Meme! в ожидаемый тип аргумента @noescape (Meme) throws -> Bool

Meme! является структурой для моего приложения. Как мне это сделать?

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
4b9b3361

Ответ 1

Сообщение об ошибке вводит в заблуждение. На самом деле вам нужно предоставить компилятору способ сравнить два экземпляра Meme и решить, на каком критерии эти экземпляры равны.

Предположим, вы хотите, чтобы два экземпляра, имеющие одинаковое свойство name, считались равными.

Мы сопоставляем структуру с Equatable и создаем оператор ==, который сравнивает две структуры по свойству имени:

struct Meme:Equatable {
    var name:String!
}

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

Теперь мы можем использовать indexOf с экземпляром Meme:

let doge = Meme(name: "doge")

let lolcat = Meme(name: "lolcat")

let memes = [lolcat, doge]

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

Если вы хотите сравнить два экземпляра не по свойству name, а по их уникальности, вам нужно будет сделать структуру соответствующей Hashable и использовать уникальное свойство hashValue, возвращающее значение 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
}

В этом примере hashValue сделан из self.name, поэтому два разных экземпляра Meme с одинаковым именем будут считаться равными. Если вы этого не хотите, используйте другой источник для хэш-значения.

Примечание: в Swift 3, indexOf стал index(of:), поэтому в этом примере мы изменили бы memes.indexOf(doge) на memes.index(of: doge).

Ответ 2

Если вы хотите поместить сравнение внутри самого метода indexOf, сделайте это так:

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

Вероятно, это не лучший способ сравнить изображения. Если вы знаете, что изображения являются одним и тем же объектом, вы можете использовать:

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

но если вы хотите сравнить их по пикселям или сравнить одно и то же изображение, масштабированное до разных размеров, это немного сложнее.