2015-04-03 2 views
0

У меня есть класс, который реализует протокол, чтобы добавить 3 переменные. Я специально установил переменную изображения, отладчик показывает, что переменная существует, но в коде, когда я печатаю ее, она показывает nil, мой оператор if let также считает, что переменная равна нулю.Переменная не ноль, но код думает, что это nil

@objc protocol DashboardItem { 

    var title: String { get } 
    var detail: String { get } 
    optional var image: UIImage { get } 

} 

class StaticDashboardItem: DashboardItem { 

    var title: String 
    var detail: String 
    var image: UIImage? 

    init(title: String, detail: String, image: UIImage) { 
     self.title = title 
     self.detail = detail 
     self.image = image 
    } 

} 

EDIT: Новый скриншот enter image description here

Журналы

nil 
2 

ответ

2

Ваш StaticDashboardItem не полностью выполняет ваш протокол DashboardItem. Он соответствует ему, но не реализует переменную var image: UIImage { get }, которую он имеет полное право не реализовывать, поскольку это соответствие optional. Таким образом, ваш StaticDashboardItem не имеет свойства/переменной image, исходящей из этого протокола.

НО, вместо этого, вы добавили еще один, совершенно не связанные свойства var image: UIImage? к вашим StaticDashboardItem, и вы, к сожалению, дали ему то же самое имя, следовательно, ваше замешательство. Но это свойство image на вашем StaticDashboardItem не совпадает с вашим протоколом DashboardItem, и именно здесь возникает ваше замешательство.

  • Если var image: UIImage? из вашего StaticDashboardItem предназначен для реализации этого необязательного image имущества из вашего протокола то типы должны совпадать, так что свойство от вашего StaticDashboardItem должно быть типа UIImage, не UIImage?.
  • Если var image: UIImage? из вашего StaticDashboardItem предназначен для совершенно другого имущества, не связанного с вашим протоколом, то вам лучше использовать другое имя, чтобы избежать путаницы.

[EDIT] Теперь, когда вы обновили свой вопрос, чтобы показать больше кода, который подтверждает мои предположения. Поскольку ваш локальный параметр dashboardItem в вашем методе configure объявлен как DashboardItem (так, протокол), то dashboardItem.image ссылается на свойство протокола (поскольку этот код не знает о StaticDashboardItem, конечно, он знает только протокол), который в ваш случай не существует (у вас нет свойства с именем image типа UIImage в этом dashboardItem, что вы интроспективно), объясняя, что println результат nil и что else ветка выполняется, вот и все, чего ожидать от вашего кода.

Единственное, что уводит вас есть отладчик подсказка, что также показывает Эйвери другие свойства объекта проверяется, даже свойства не ограничивается теми, от вашего типа протокола DashboardItem, поэтому в том числе image: UIImage? имущества и любые другие исходя из StaticDashboardItem реального типа вашего объекта.

+0

Да, именно поэтому я приглашал его на мой обмен комментариями, чтобы показать, как объявлен 'dashboardItem'. Теперь мы знаем, что (как я подозревал) это DashboardItem, поэтому свойство 'image' в его коде является (необязательным) _protocol_' image', а не (необязательным) экземпляром. – matt

+0

Yup, и это совершенно разумно, поэтому здесь нет ошибки Swift, все абсолютно логично. – AliSoftware

+0

Плюс он должен будет учитывать тот факт, что необязательный член протокола сам обернут в Необязательный. Вот почему он получает «ноль»; это _that_ Необязательно, и он сообщает, что «этот необязательный элемент не реализован». Даже если бы это было реализовано, ему нужно было развернуть его, чтобы получить изображение. И если он переписывает необязательный член как необязательный, он будет _double-wrapped_. В моей книге рассказывается об этом: http://www.apeth.com/swiftBook/ch04.html#SECoptionalProtocol – matt

1

Вы заблуждаясь, кстати отладчик работает. На вашем снимке экрана мы остановили до переменную, значение которой вы изучаете. Таким образом, ваш наконечник инструмента, показывающий значение dashboardItem, не всегда является точным. Значение dashboardItem действует для строк до линии, где мы приостановлены, а не для строк после линии, на которой мы остановились.

+0

он говорит nil, посмотрите на результат println в отладчике. Также, если перейти к разделу else – aryaxt

+0

Тогда это нуль. В чем проблема? – matt

+0

Отладчик показывает некоторые из них по выбору, поэтому он не должен быть nil – aryaxt

Смежные вопросы