Не удается преобразовать значение типа ‘Объект.Тип» к ожидаемому типу аргумента «Объект»

#swift #class

Вопрос:

Я новичок в Swift, поэтому прошу прощения, если это глупый вопрос. Я пытаюсь выделить объект и передать его самому родителю.

То, что у меня есть, похоже:

   class Maze { 
      var rat : MazeRat 

      init () {
        
        rat = MazeRat(self: Maze)
    }

  }

and

class MazeRat{
     init( maze : Maze ) {
        
    }
}
 

Но XCode возражает против «я» в вызове, настаивая на том, что это должен быть «лабиринт». Но если это изменение будет внесено, я получу ошибку:

   Cannot convert value of type 'Maze.Type' to expected argument type 'Maze'
 

ТИА за любую помощь.

Комментарии:

1. Здесь нет родителей, поэтому мне любопытно, чего вы пытаетесь достичь?

2. Ну, извините, если я не совсем ясно выразился, я думаю о Лабиринте как о родителе, а о Крысе как о ребенке, поскольку она является членом Лабиринта.

3. Должна ли крыса иметь ссылку на лабиринт, разве недостаточно одной ссылки на направление?

Ответ №1:

Вы должны ссылаться на текущий экземпляр Maze as self .

Обратите внимание, что в каждом примере unowned здесь используются weak ключевые слова или, чтобы предотвратить сильную ссылку между Maze и MazeRat .

Однако, поскольку self он еще недоступен, так как rat не был инициализирован — сначала вам нужно указать rat начальное значение.

Пример:

 class Maze {
    private(set) var rat: MazeRat!

    init() {
        rat = nil
        rat = MazeRat(maze: self)
    }
}

class MazeRat {
    unowned let maze: Maze

    init(maze: Maze) {
        self.maze = maze
    }
}
 

Другой метод-инициализировать MazeRat , а затем установить maze экземпляр, например так:

 class Maze {
    let rat: MazeRat

    init() {
        rat = MazeRat()
        rat.maze = self
    }
}

class MazeRat {
    weak var maze: Maze?

    init() {}
}
 

Комментарии:

1. Спасибо тебе, Джордж. Это то объяснение, которое мне было нужно.

2. Небольшое продолжение. Поскольку элемент лабиринта в MazeRat теперь является необязательным, все ссылки на Лабиринт должны быть развернуты, т. е. лабиринт!. nRow и т. Д. Допустимо ли, хорошая практика или не одобряется делать что-то вроде let uwMask = маска! Просто чтобы избежать челки повсюду.

3. @rkwright Я отредактировал первый пример, чтобы использовать unowned его . Теперь, в MazeRat , вы можете ссылаться maze без дополнительных опций. Вы не должны принудительно разворачивать weak переменные, так как они могут быть nil в то время, когда вы их читаете.

4. @rkwright Разница между weak и unowned (даже для меня) по-прежнему является одной из самых трудных для понимания вещей. Здесь есть хорошая цитата, а под ней абзац, объясняющий, почему unowned это может быть лучше для вашей ситуации. "If you know your reference is going to be zeroed out properly and your 2 references are MUTUALLY DEPENDENT on each other (one can't live without the other), then you should prefer unowned over weak" .

5. @rkwright В основном weak следует использовать здесь , если у вас может быть MazeRat экземпляр, который больше не принадлежит a Maze , в чем я сомневаюсь, что это будет ваш случай.