Лекция 1 CS196P Весна 2016 и слайды на английском языке находятся на iTunes название “1. Course Overview and introduction to iOS, Xcode, and Swift.”
Ниже представлен неавторизованный русскоязычный конспект Лекции 1, который состоит из двух частей:
Первая часть Лекции 1 CS193P Весна 2016 — 0 — 60 минута находится
здесь,
Вторая часть Лекции 1 CS193P Весна 2016 — 60 — 77 минута — находится в этом посте.
Код демонстрационного примера для Лекции 1 находится на Github для Xcode 7 и Swift 2.2. Для Swift 3.0 и Xcode 8 код находится на Github, а для Swift 3 .2 и Xcode 9 — также на Github.
—————— 60-ая минута Лекции ——————
Так что идем дальше и добавляем дисплей на наш пользовательский интерфейс.
Будем добавлять дисплей сверху. Мы хотим что-то подобное тому, что на стандартном калькуляторе, пришедшим вместе с операционной системой Mac, и чтобы в правом углу был «0», но, возможно, с другими цветами.
Я возвращаюсь в Область Утилит в окно Палитра, откуда я доставал свои кнопки для цифровой клавиатуры. Теперь я буду перетягивать метку — Label, которая представляет собой readonly текст.
Пользователь не может касаться метки и затем печатать туда что-то с помощью маленькой клавиатуры на iPhone. Это readonly текст, и именно его мы хотим иметь на нашем калькуляторе.
Я помещаю ее на моем пользовательском интерфейсе точно также, как и прежде помещал кнопки:
Я могу изменять размер метки,
могу изменять размер шрифта. Давайте сделаем метку реально большой и установим размер шрифта 40 point.
Я могу даже выравнять текст метки вправо, как это принято у калькулятора:
Может быть, я поменяю фон для дисплея и сделаю его голубым:
Мне не нравится черный на голубом, лучше белый на голубом. Давайте установим это:
Я могу переместить куда угодно и выравнять мой дисплей с помощью голубых линий:
Это очень важно, потому что я собираюсь делать мой UI гибким и адаптированным в Среду. Но пока не буду этого делать.
Теперь подумаем о том, как подсоединить дисплей к нашему Controller. Это делается немного по-другому, чем в прошлый раз, когда мы подсоединяли кнопки, потому что это не тот случай, когда пользователь касается нашей метки, и мы должны вовлечь в это действие метод. Это другой случай. Я хочу говорить с этой меткой. Я хочу размещать определенные цифры на дисплее. В данном случае направление взаимодействия осуществляется от Controller к дисплею вместо направления от кнопки к Сontroller. Соединять мы будем метку с Сontroller тем же самым способом: при нажатой клавиши CTRL будем тянуть от метки к нашему Сontroller,
но на этот раз вместо Action мы выберем Outlet.
Outlet означает, что вместо метода создается свойство (property) или переменная экземпляра класса. Это напоминает currentTitle, который также является переменной экземпляра класса. Это свойство указывает на дисплей, так что у нас есть к нему доступ в любое время. Я хочу назвать это свойство display.
К счастью Type указан правильно. Это UILabel, а не AnyObject. Это хорошо, потому что Xcode точно знает, что это UILabel. И не беспокойтесь о Storage, Weak или Strong, мы будем говорить об этом на следующей неделе, а сейчас вы можете это просто игнорировать. Я нажимаю кнопку Connect и Xcode создает свойство вместо метода.
И опять @IBOutlet — это что-то, что размещает XСode, кроме этого он размещает еще маленький кружочек здесь же. Если вы наведете мышку на этот кружочек, то увидите к чему на UI подсоединен этот @IBOutlet.
Или @IBAction.
Вы можете игнорировать @IBOutlet. Я сказал вам, что вы можете игнорировать Weak или Strong, вы также можете игнорировать и weak. Но var display: UILabel! вам более знакомо, оно похоже на var currentTitle. Свойство display — это свойство нашего Controller или переменная экземпляра класса (instance variable), если вы хотите думать таким образом. Свойство display имеет тип : UILabel !. Что же здесь означает восклицательный ! знак? Я думал, что восклицательный ! знак — это «развернутое» Optional, почему здесь-то оно присутствует? Здесь это не имеет смысла. Но фактически вы можете поставить здесь вопросительный ? знак, потому что восклицательный ! знак также означает Optional. Он означает тот же самый Optional, что и вопросительный ? знак.
Я оставлю здесь вопросительный ? знак и продолжу работать над демонстрационным примером. Затем мы вернемся к нему и заменим его на восклицательный ! знак, чтобы показать, что он означает в этом контексте. Но восклицательный ! знак и вопросительный ? знак, оба, означают Optional при декларировании. Итак, у меня есть display.
Когда я касаюсь цифр на цифровой клавиатуре, я хочу, чтобы они добавлялись к тому, что уже есть на дисплее display. Давайте сделаем это, но вначале избавимся от печати на консоли. Нам не нужно этого больше делать.
Я создам другую локальную переменную, которая тоже будет константой, и это let. Я назову эту локальную переменную textCurrentlyInDisplay.
Я хочу получить текст, который находится в настоящий момент на дисплее display. И сообщение, которое мы пошлем display, — text. Мы можем посмотреть это в документации.
Это даст мне текст, который находится на дисплее. Это метод UILabel. Но тут же появляется ошибка. Ошибка состоит в том, что я должен «развернуть» display. Вы видите, что display является Optional меткой UILabel. Вы не можете послать сообщение text типу Optional, тип Optional не понимает сообщения text.
UILabel понимает сообщение text, так что нам нужно получить ассоциированное значение display, которым является UILabel, и мы можем это сделать здесь с помощью восклицательного ! знака. И опять, заметьте, что Xcode предлагает исправить эту ошибку, я соглашаюсь исправить ошибку и ставлю в конце восклицательный ! знак.
Теперь это «развернутое» Optional UILabel, и я ему посылаю сообщение text. На самом деле text — это свойство, наподобие currentTitle, которое также является свойством, но свойство кнопки UIButton, а text — это свойство метки UILabel. Если мы используем option+click на свойстве text, то мы увидим, что var text является Optional String.
Почему? Потому что UILabel может быть не установлена. text в ней, может быть, не установлен. Он также является Optional, как и currentTitle. Так что нам нужно и его «развернуть».
—————— 65-ая минута Лекции ——————
Теперь у меня String. Мне кажется, что вы, как и я, устали от всех этих восклицательных ! знаков, и мы собираемся избавиться то них. Через несколько секунд, так что не беспокойтесь.
Но по-любому у меня теперь есть текущий текст дисплея display. И я могу написать следующий код:
Заметим, что вы можете использовать «+» для конкатенации строк. Некоторые языки разрешают, некоторые — нет. Swift разрешает. Заметьте также, что, когда я устанавливаю значение Optional, помните? здесь text — это Optional String, я могу установить его так, чтобы оно было String, что означает, по определению, установку Optional в значение «установлено» и использование его ассоциированного значения.
Теперь давайте посмотрим, как я смогу установить это Optional в значение «не установлено» ? Кто-нибудь знает? Вы говорите, что нужно установить эту вещь в nil.
Это ключевое слово, означает, что Optional «не установлено«. Если мы таким образом установили этот text, то он будет пустым. Таким образом, когда вы устанавливаете Optional, то вы можете установить его либо в nil, либо в ассоциированное значение.
Звучит хорошо. Давайте запустим приложение
Я надеюсь, что если мы будем нажимать кнопки с цифрами, то они начнут появляться на дисплее display в конце. Нажимаем «5» — появилась, «8», «9» — все появляется, но мне не нравится «0» в самом начале:
Нуль «0» — так калькулятор не работает. Когда я нажимаю «5», то я начинаю печатать новое число. Нам необходимо избавиться от «0». Нам необходимо найти способ, с помощью которого мы сможем отслеживать, находимся ли мы в процессе набора числа или нет. Потому что, если мы находимся в середине набора числа, то мы добавляем цифры в конец display, а если нет, то мы просто заменяем все, что находится на дисплее display, на то, что мы печатаем. Поэтому я собираюсь добавить новую переменную, переменную экземпляра класса, новое свойство с именем userIsInTheMiddleOfTyping.
Теперь вы смеетесь, потому что вам кажется, что это такое длинное имя и вам придется очень много раз печатать его снова и снова, но вам больше никогда не придется его печатать. Потому что Xcode всегда сам заканчивает слова вместо вас. Так что длинные имена, в действительности, хорошо. Вы можете выбрать более короткое имя, чем то, что оно могло бы выражать, но, как вы знаете из информатики, правильное именование — это прежде всего хорошо для того, кто читает ваш код. Поэтому наше новое свойство имеет имя userIsInTheMiddleOfTyping и тип Bool.
Это не Optional Bool. Это просто Bool. Так что нет вопросительного ? знака. Оно просто либо true, либо false. Либо я нахожусь в середине набора числа, либо — нет.
Но как только я добавил тип Bool, я получил ошибку. Видите ошибку? Но почему она появилась в верхней части кода, ведь я там ничего не делал? Давайте посмотрим, что за ошибка?
У класса ViewController нет инициализаторов. Вы будете делать ваше Домашнее Задание и у вас будет происходить то же самое, вы будете удивляться: «Что такое? Я ничего не сделал, просто напечатал переменную var?» Что означает эта ошибка? Мы получили с вами ошибку потому, что в Swift все свойства (properties), абсолютно каждое свойство, должно иметь начальное значение. Вам не разрешается иметь свойства, у которых нет начальных значений. Как мы дадим начальное значение этому Bool свойству?
Есть два способа. Один способ — это создание инициализатора, о чем, собственно, и говорит предупреждение. Но я не собираюсь говорить об инициализаторах раньше следующей недели. Я не могу этого сделать сейчас, потому что я еще не говорил об этом. Какой другой способ мы можем использовать?
Мы можем просто написать = false. Мы просто инициализируем наше свойство, и ошибка уйдет.
Ура! У нас все получилось, но некоторые из вас могут сказать: «А как же насчет display? Мы не инициализировали это свойство?»
Это потому, что с Optionals мы будем обращаться особым образом. Они всегда инициализируются автоматически со значением «не установлено«.
Это происходит всегда, если у вас есть var, которая является Optional. Это имеет определенный смысл: у вас есть Optional и она будет «не установлена» до тех пор, пока вы ее не установите во что-то. Так что все Optionals начинают со значения «не установлено«. Именно поэтому считается, что у Optional всегда есть начальное значение:
Еще я хочу спросить вас, нужно ли нам декларировать : Bool?
Нет. Почему нам это не нужно? Потому что значение false может быть только у Bool, так что Swift сможет «вывести тип из контекста» (infer) и установить, что это тип Bool. Видите?
Теперь давайте использовать userIsInTheMiddleOfTyping, и именно с этим свойством мы можем накапливать цифры на дисплее display или начинать все сначала. Мы будем использовать if предложение.
—————— 70-ая минута Лекции ——————
Если пользователь находится в середине набора числа, то мы будем накапливать цифры, если нет, то мы устанавливаем на дисплее display напечатанную цифру. Если я начинаю печатать «5» или что-то еще, то это полностью заменит все, что было на дисплее display до этого. И, конечно, в любом случае мы должны установить userIsInTheMiddleOfTyping в true, потому что как только мы коснулись цифры digit, мы уже находимся в середине набора числа.
Теперь я уже порядком устал от печатания каждый раз display с восклицательным ! знаком. Каждый раз, когда я печатаю display с восклицательным ! знаком, я, фактически, точно знаю, что display всегда «установлен«. Единственный раз, когда он «не установлен» и длится это наносекунду, это когда он начинает появляться на экране, перед тем, как у iOS появляется шанс «подвязать» его к нашей метке UILabel. Но как только он «подвязан», он «установлен» навсегда. И, конечно, когда пользователь касается кнопок с цифрами, пользовательский интерфейс (UI) полностью находится на экране, все «подвязано» и я точно знаю, что display никогда не будет равен nil. Никогда в этом коде. Так почему же я продолжаю снова и снова набирать display с восклицательным ! знаком? Ответ заключается в том, что мы не должны этого делать, потому что мы вернемся назад и заменим вопросительный ? знак восклицательным ! знаком.
Если вы разместили восклицательный ! знак при декларировании, то это говорит о том, что любой может использовать это свойство и оно будет «неявно развернуто» (implicitly unwrap). Оно будет автоматически «разворачиваться». Но если оно разворачивается, когда оно равно nil, то происходит аварийное завершение приложения. Итак, это позволяет мне избавиться от всех восклицательных ! знаков, потому что при декларировании вместо вопросительного ? знака я разместил восклицательный ! знак.
Все это поняли?
И опять, если я вернусь назад и восстановлю вопросительный ? знак при декларировании, то я получу ошибки, потому что я «не развернул» Optional,
но, если я опять помещу восклицательный ! знак при декларировании, то теперь декларируемое свойство везде является «неявно развернутым» (implicitly unwrapping). Это называется implicitly unwrap Optional (неявно развернутое Optional). Это очень важно.
Теперь запустим приложение и посмотрим, исправились ли наши ошибки?
Нажимаем «5» — избавились от нуля. Все работает.
Мы проделали прекрасную работу и наша цифровая клавиатура полностью функционирует.
Теперь нам нужно добавить операции. Из-за ограниченного времени я добавлю только кнопку с ?. Это очень простая операция, которая заключается в том, что на дисплее display размещается ?. Давайте сделаем это. Я собираюсь скопировать и вставить кнопку «7».
В действительности, это очень плохая идея, и вы увидите это через секунду. Но я сделаю это и назову эту кнопку ?.
Конечно, ? — это не цифра. Это операция и я выполню CTRL-перетягивание, чтобы создать новый другой Action, отличный от того, который был создан для цифр.
Этот Action назовем performOperation, потому что ? — это операция. Все кнопки с операциями будут иметь Action с именем performOperation.
И не забудьте заменить AnyObject на UIButton, как и в вашем Домашнем Задании.
Нажимаем кнопку Connect и получаем performOperation прямо здесь:
В performOperation я сделаю то же самое, что я делал в начале метода touchDigit. Я спрошу sender, какую операцию он представляет?
Конечно, мне нужна строка String и я ставлю восклицательный ! знак. Но если на кнопке пустой заголовок,
я хотел бы игнорировать нажатие кнопки с такой операцией, вместо аварийного завершения приложения. А что, если вообще вполне законно иметь кнопку с пустым заголовком? Я хочу «разворачивать» только тогда, когда заголовок кнопки «установлен«. Способ, каким мы можем это сделать — не ставить восклицательный ! знак, а поставить в начале предложения if. В этом случае хорошо, что не надо много печатать и выглядит так, как и читается. Если я могу выполнить присвоение
let mathematicalSymbol = sender .currentTitle, то я могу что-то сделать в этом случае.
Это хорошо читается по-английски и, действительно, прекрасный способ «развернуть» Optional. Внутри этого if, mathematicalSymbol будет строкой String.
Это будет ассоциированное значение currentTitle. За пределами этого if, mathematicalSymbol даже не определено. Все супер просто.
Далее продолжим с mathematicalSymbol. Если mathematicalSymbol = ?, то я могу установить мой display, и я больше не использую восклицательный ! знак, в константу M_PI, которая является Double положительным значением ?.
Теперь у нас появилась ошибка. Почему это ошибка появилась?
Потому что нам говорят, что нельзя присвоить значение тип Double чему-то, что имеет тип String?. Мы знаем, что display.text является строкой и имеет тип String?, следовательно, мы не должны делать такое присваивание. Как мы можем преобразовать Double в String? Ответ состоит в том, что мы должны создать новую строку. Сейчас вы увидите, как создается новый экземпляр объекта в Swift.
——————75-ая минута Лекции ——————
Для этого вы просто пишите имя класса, а затем круглые скобки, внутри которых вы размещаете все, что этот класс допускает при создании нового экземпляра. И у вас есть множество возможностей. Например, это могут быть инициализаторы, на которые мы ссылались раньше. К счастью, String в состоянии взять Double в качестве одной из таких вещей, так как она знает, как создать новую строку String из Double.
Запускаем приложение, убеждаемся, что цифровая клавиатура работает и нажимаем кнопку ?.
У нас проблема, так как не все цифры помещаются на нашем дисплее. Мы можем очень быстро это исправить. Вернемся обратно. В Инспекторе Атрибутов для нашего дисплея display есть замечательная «фишка» с именем Autoshrink, благодаря которой метка display будет автоматически «сжиматься», но не менее, чем до 9 point.
Но у нас есть еще одна проблема. Опять запускаем приложение и нажимаем кнопку ?.
Что это такое? В конце числа мы видим символ ?. Продолжаем нажимать цифры: «9», «6» и т.д..
Это какой-то беспорядок. На самом деле у нас две проблемы здесь.
По некоторой причине, когда мы нажимаем кнопку ?, то в конце display появляется символ ? в конце. Почему? Это происходит по следующей причине. Смотрим на маленький кружочек слева
Кнопка ? посылает Action performOperation. А как насчет Action touchDigit ?
Кнопка ? также посылает и Action touchDigit. Вы видите, что кнопка ? заставляет работать оба метода: и touchDigit, и performOperation. Это произошло потому, что я скопировал и вставил кнопку «7», которая посылает сообщение touchDigit и затем добавил еще одно — performOperation. Как нам исправить это? Для этого нужно на кнопке ? кликнуть правую кнопку мыши (или удерживая CTRL, просто кликнуть на мышке). Если вы кликните правую кнопку мыши на чем-нибудь из вашего UI, то вы увидите все связи этого элемента UI.
Очень важно понимать, что происходит, если вы кликните правую кнопку мыши на вашем UI. В случае с нашей кнопкой ?, мы видим две связи: c touchDigit: и с performOperation: , так что я буду избавляться от связи touchDigit: . Для этого достаточно нажать на маленький крестик слева вверху touchDigit: .
Теперь связь touchDigit: ушла и осталась только performOperation: .
Эту проблему, связанную с размещение символа ?, мы решили. Но другая проблема пока осталась. Она заключается в том, что если я нажал кнопку ?, а затем продолжаю печатать цифры, то приложение думает, что я нахожусь в середине набора числа, и добавляет печатаемые цифры в конец дисплея . Эту проблему исправить очень легко: я просто напишу
userIsInTheMiddleofTypingNumber = false
в методе performOperation, это сотрет все, что было на дисплее display до этого и, очевидно, теперь я не буду находиться в состоянии, когда я печатаю число.
Теперь у нас есть полностью функционирующий калькулятор с одной операцией. Запускаем приложение. Набираем «4» «5» «?«
В Среду мы сделаем более мощный калькулятор.
— Конец Лекции 1 ——
Татьяна, огромное спасибо за ваши статьи! Реально помогают научиться азам программирования на Swift и познакомиться с экосистемой iOS…
Татьяна, спасибо за Ваш труд!
Благодаря Вашим переводам вышел на курсы Пола Хагерти, однако почти сразу перешел на текущий курс по iOS 9 Swift 2.2.
Подскажите, уже есть тема для разбора домашних заданий по текущему курсу? Первое задание готово, хотелось его обсудить.
Также могу предложить посильную помощь по переводам.
Спасибо. Мне очень нужна ваша помощь. Подробности сообщу по email в самое ближайшее время.
Хорошо!
Кстати, всем советую обязательно читать reading assingnment по документации Apple, которая написана очень хорошо и доступно. Многие вопросы отпадают сами собой.
Татьяна, спасибо больше за труд! Хотелось бы узнать будет ли продолжение и как скоро?
Сегодня или завтра выложу Лекцию 2. Намерена переводить все Лекции и выполнять все Задания, как и прошлый курс по iOS 8.
Огромное спасибо, Татьяна!
Татьяна, скажите, я начинал предыдущий курс, потом оставил.. Есть смысл его завершать, чтобы приступить к этому? Или сразу начинать курс 2016?
Сразу начинайте курс 2016, потому что он читается для новой версии Swift 2.2 и с прицелом на Swift 3.0, а курс 2015 читался для Swift 1.0. Изменений произошло много. Кроме того, в курсе 2016 намного проще демонстрационный пример и Задания, связанные с Калькулятором. В курсе 2015 RPN калькулятор с рекурсией, и можно просто «потонуть» в особенностях его реализации в Задании 2. Но если вы любите сложные Задания, то это то, что надо. Но я бы не стала сбрасывать курс 2015 со счетов, потому что что-то, что было в курсе 2015, не будет представлено в курсе 2016. Если вы это обнаружите, то сможете вернуться к курсу 2015 и освоить этот недостающий материал.
первая лекция есть в pdf файле?
Будет позже.
Отличная работа!
Шикарно… Больше и сказать нечего…
Спасибо ВАм огромное за проделанную работу. На ваш взгляд какой из трёх курсов более информативен в плане самой iOS и понимания всех необходимых паттернов для разработки приложений для apple: iOS7, iOS8, iOS9. Я прошёл 11 лекций iOS7, но к сожалению сделав большой перерыв, понял что для выполнения заданий — нужно заново просматривать и делать предыдущие — поэтому начал сразу с iOS 9 или стоит закончить iOS7?
Все зависит от того, на чем вы будете писать ваши приложения: на Swift или Objective-C. Если на Swift, то однозначно — курс iOS 9.
Если Objective-C, то все равно нужен курс iOS 9,но для Objective-C ( на моем сайте его нет,
хотя я как могла старалась адаптировать курс iOS 7 Objective-C к iOS 9).
Я бы сделала как вы — iOS 9, тем более, что это курс для Swift 2.2, а iOS 8 — для Swift 1.1, который к настоящему времени сильно изменился.
Профессор в курсе iOS 9 по-моему превзошел сам себя, он на протяжении всего этого курса все очень подробно и понятно объясняет,
чего не делал на iOS 8 и iOS 7.
Хотя в курсе iOS 8 есть разделы, которых не будет в iOS 9.
Начинайте с iOS 9 и выполняйте Домашние Задания.
Если вам удастся каким-то (любым) путем их выполнить, считайте, что вы специалист по разработке iOS приложений.
Татьяна спасибо за ответ.
У меня свои идеи, которые я хочу воплотить в реальность и мне скорее важно актуальность материала, нежели язык. iOS 7 курс понравился тем, что было очень сложно и приходилось искать информацию и практически все нюансы стирал до дыр, чтобы решить задания. А какие темы стоит посмотреть с курса iOS8 на ваш взгляд, которые в полной мере не раскрыты в iOS9?
«Если вам удастся каким-то (любым) путем их выполнить, считайте, что вы специалист по разработке iOS приложений.»
В данный момент я досматриваю 2 лекцию и пока что мне кажется всё достаточно лёгким в отличии от iOS7 и задания MATCHSIMO я сидел по 12 часов дня 3, чтобы понять на 80% происходящее или в курсе iOS9 потом будет очень жёстко? Какой на Ваш взгляд самый сложный курс?
Я с вами согласна: самое интересное и для меня тоже — это выполнение Домашних Заданий.
Да, самый сложный курс с точки зрения Домашних Заданий — это iOS 7, но там сложность не только в Заданиях Matchismo, другие Задания 5 и 6 Photomania с Core Data — тоже супер сложные. Если вы остановились на 11 Лекции, то самое сложное — а именно background Fetch (подкачка данных в фоновом режиме) на Лекциях 13 и 14 — у вас еще впереди. Вот где реально сносит «голову», а вы должны это выполнить в Задании 5 и /или 6 да еще с Core Data да еще когда отношение «Many-To-Many». Если попробовать выполнить эти Задания для современной iOS 9 (Objective-C или Swift), используя Адаптивный Интерфейс с одной storyboard и для iPhone, и для iPad, то сложность еще возрастает на порядок. Кстати, на этом сайте можно посмотреть статьи на эту тему «Дополнение к Лекциям 15, 16 и 17 Stanford CS 193P iOS 7. Адаптивный интерфейс с двумя storyboards для iOS 9». или Адаптивные SplitViewController и Popover для iOS 9. (Swift). Часть 1, Часть 2.
Первые 3 Задания курса iOS 8 — Калькулятор ( не просто калькулятор, а RPN калькулятор) — это супер сложные, даже по сравнению с Matchismo, Задания с рекурсией. Задание 3 «Графический калькулятор» — одно из самых красивых и самых неоправданно сложных заданий. Задание 4 Smashtag — сложное и очень полезное. Там есть все: и Table View Controller (в необычном ракурсе) и Collection View Controller и нестандартный прием с Unwind Segue.
Задание 5 Dynamic Animation — игра, если выполнять до конца, то получается очень красиво, у меня даже есть статья на этом сайте «Задание 5. Решение. Ощутите «магию» Swift на простейшей игре c Dynamic Animation (часть 2)»
Кстати в курсе iOS 8 профессор представил тему Air Drop, которой не было раньше и, похоже, нет в iOS 9 (это не точно). На эту тему у него великолепный демонстрационный пример. Вообще демонстрационные примеры курса iOS 8 — великолепны.
Задания с калькулятором курса iOS 9 кажутся немного облегченными по сравнению с iOS 8 — нет рекурсии, что я считаю достоинством, а не недостатком.
Но, как всегда, с Полом Хэгерти, это только в начале. Уже Задание 2 и 3 — почти такой же сложности, как и в курсе iOS 8. В iOS 9 будет 6 Заданий, а не 5 как в iOS 8, и будет Core Data. Он уже предупредил на Лекции 11, что все будет зависеть от схемы базы данных, так что все будет очень не просто.
Но все равно я бы стала программировать на Swift. У него такие виртуозные синтаксические конструкции, что действительно ощущаешь «магию».
Попробуйте выполнить Задания 2 и 3 для iOS 9. Если захотите «погорячее», то смело выполняйте Задания iOS 8, но опираясь на Лекции по iOS 9. В лекциях по iOS 9 он объясняет все и каждое его слово на вес золота.
А верно ли я понял:
@IBOutlet weak var display: UILabel!
При декларации свойства(в данном случае это объект, который оживёт со storyboard’a), то есть display указатель на объект класса UILabel.Вне зависимости поставим мы ! или ? тип остаётся Optional, так как это декларация и значение не присвоено и равно nil, а !(unwrap Optional) работает только в случае когда с левой стороны у нас переменяя без типа var words, а после = display.text. И в нашем примере мы ставим !, только для того , чтобы дальше в коде было проще работать с указателем display на объект класса UILabel, так как мы точно знаем, что к этому указателю будет присвоен объект нужного нам класс. Верно всё? как вообще тогда назвать, если не unwrap Optional наш случай с ! ?
Да, вы правильно поняли. Переменная display — это Optional, то есть у нее два состояния — неопределен и тогда это nil, и определен и тогда у него есть ассоциированное значение — UILabel. Если это Outlet, как в нашем случае, то он «подвязывается» системой на этапе загрузки вашего MVC со storyboard и к моменту написания нами кода он почти всегда определен, то есть установлен системой, поэтому мы смело его «разворачиваем», то есть извлекаем ассоциированное значение UILabel, и превращаем display из Optional в обычную UILabel, т . е. «развернутое» Optional значение. Дальше мы имеем дело с обычной UILabel. Если вы посмотрите на Outlets, то они все с восклицательным ! знаком. Есть небольшой промежуток времени, когда display имеет значение nil. Например, у вас есть другая метка и там вы пишите код в didSet{} для этой метки, сама другая метка уже установлена, а насчет нашей метки display мы не имеем право предположить, что она установлена и мы должны рассматривать ее как Optional и писать display?. Далее в Лекциях эта ситуация всегда будет оговариваться: «Еще не все Outlets установлены.» В этом случае пишем display?.
В чем конкретно ваш вопрос?
Спасибо за объяснение, но видимо я не корректно задал вопрос- меня интересовало как — это все называется. Но я сам разобрался вот:
@IBOutlet weak var display: UILabel? в данном случае это просто Optional
@IBOutlet weak var display: UILabel! а здесь Implicitly Unwrapped Optional и главное тут не путать со стандартным Unwrapped Optional
Да, вы правы. Восклицательный знак ! и означает явно (Implicitly) развернутое Optional.
Ведь развернуть Optional можно неявно в коде с помощью конструкции
@IBOutlet weak var display: UILabel?
.................
if let displayUnwrapped = display {
displayUnwrapped.text =
}
@IBOutlet weak var display: UILabel?
……………..
if let displayUnwrapped = display {
displayUnwrapped.text =
}
Данный кусок кода читается так: если display не nil, то тогда будет выполнятся код в if , а переменная displayUnwrapped рассматривается, как YES/NO , но и также будет в себе хранить значение, так?
У меня к Вам вопрос болле личного характера. Вы сами работаете программистом и параллельно делаете людям добро переводя Стэнфорд на русский?
Нет. Код читается не так, как вы сказали. Это не if оператор, а конструкция if-let. Она означает, что мы пытаемся развернуть Optional переменную display, и если значение для display установлено, то мы извлекаем ассоциированное значение ( в данном случае UILabel) в локальную константу displayUnwrapped и далее в фигурных скобках можем работать с уже развернутой константой displayUnwrapped типа UILabel, а значит мы можем присвоить этой метке атрибуты (в данном случае) text и никаких знаков — ни вопросительного ?, ни восклицательного нам не нужно. Константа display Unwrapped называется Unwrapped Optional. Если значение display не установлено, то мы не выполняем ничего. В этом смысле синтаксическая конструкция if-let более безопасная, чем Implicitly Unwrapped Optional display!, так как в случае, если начение display не установлено, то мы получим аварийное завершение программы.
Позвольте мне уклониться от вопросов личного характера.
спасибо за очередное разъяснение
Вот это титанический труд! Невероятно, что еще есть люди, которые способны безвозмездно проделать такой колоссальный обьем работы. Это удивительно! Огромное Вам спасибо за труды во благо других, кому это столь необходимо!!! Очень Вам благодарен!!!!
Спасибо за добрые слова.
:))) c 5ой или 6ой лекции все будет платно, не переживайте
XCode8.1 не совсем понял как вставить символ Пи ( заменил просто «Pi», копи-паста не работает — вместо символа знак «?» в кнопке). Спасибо в любом случае.
не сработало.
Что не сработало? Вставка ?? Все работает.
Нажимаете Alt и P
Татьяна, у вас собраны шикарные материалы на сайте.
Только верстка почему-то поехала — у меня на экране текст статьи отображается прям поверх картинок. (и не только в этой статье)
Меня предупредили, что 8 ноября ( 8pm MT) на bestkora.com проводится плановый переход на MySQL версии 5.6 для улучшения стабильности и безопасности. Возможно, вы попали на какой-то переходной период. Спасибо за предупреждение. Я буду следить за этим.
Да. Теперь вижу накладки картинок на текст. Это происходит только в Chrome, в Safari этих накладок нет. Буду с этим работать. Еще раз спасибо, что сообщили.