Лекция 1 CS193P Spring 2016 — Обзор курса и введение в iOS, Xcode и Swift. (часть 2)

screen-shot-2016-11-05-at-3-16-24-pm

Лекция 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 текст.

Screen Shot 2016-04-25 at 8.40.47 AM

Пользователь не может касаться метки и затем печатать туда что-то с помощью маленькой клавиатуры на iPhone. Это  readonly текст, и именно его мы хотим иметь на нашем калькуляторе.

Я помещаю ее на моем пользовательском интерфейсе точно также, как и прежде помещал кнопки:

Screen Shot 2016-04-25 at 8.43.51 AM

Я могу изменять размер метки,

Screen Shot 2016-04-25 at 8.48.24 AM

могу изменять размер шрифта. Давайте сделаем метку реально большой и установим размер шрифта 40 point.

Screen Shot 2016-04-25 at 8.50.31 AM

Я могу даже выравнять текст метки вправо, как это принято у калькулятора:

Screen Shot 2016-04-25 at 12.57.38 PM

Может быть, я поменяю фон для дисплея и сделаю его голубым:

Screen Shot 2016-04-25 at 1.20.12 PM

Мне не нравится черный на голубом, лучше белый на голубом. Давайте установим это:

Screen Shot 2016-04-25 at 1.24.20 PM

Я могу переместить куда угодно и выравнять мой дисплей с помощью голубых линий:

Screen Shot 2016-04-25 at 1.26.36 PM

Это очень важно, потому что я собираюсь делать мой UI гибким и адаптированным в Среду. Но пока не буду этого делать.

Теперь подумаем о том, как подсоединить дисплей к нашему Controller. Это делается немного по-другому, чем в прошлый раз, когда мы подсоединяли кнопки, потому что это не тот случай, когда пользователь касается нашей метки, и мы должны вовлечь в это действие метод. Это другой случай. Я хочу говорить с этой меткой. Я хочу размещать определенные цифры на дисплее. В данном случае направление взаимодействия осуществляется от Controller к дисплею вместо направления от кнопки к Сontroller. Соединять мы будем метку с  Сontroller тем же самым способом: при нажатой клавиши CTRL будем тянуть от метки к нашему Сontroller,

Screen Shot 2016-04-25 at 4.39.54 PM

но на этот раз вместо Action мы выберем Outlet.

Screen Shot 2016-04-25 at 4.41.34 PM

Outlet означает, что вместо метода создается свойство (property) или переменная экземпляра класса. Это напоминает currentTitle, который также является переменной экземпляра класса. Это свойство указывает на дисплей, так что у нас есть к нему доступ в любое время. Я хочу назвать это свойство display.

Screen Shot 2016-04-25 at 5.19.32 PM

К счастью Type указан правильно. Это UILabel, а не AnyObject. Это хорошо, потому что Xcode точно знает, что это UILabel. И не беспокойтесь о Storage, Weak или Strong, мы будем говорить об этом на следующей неделе, а сейчас вы можете это просто игнорировать. Я нажимаю кнопку Connect и Xcode создает свойство вместо метода.

Screen Shot 2016-04-25 at 5.27.06 PM
И опять @IBOutlet — это что-то, что размещает XСode, кроме этого он размещает еще маленький кружочек здесь же.  Если вы наведете мышку на этот кружочек, то увидите к чему на UI подсоединен этот @IBOutlet.

Screen Shot 2016-04-25 at 5.30.37 PM

Или @IBAction.

Screen Shot 2016-04-25 at 5.42.05 PM

Вы можете игнорировать @IBOutlet. Я сказал вам, что вы можете игнорировать Weak или Strong, вы также можете игнорировать и weak. Но var display: UILabel! вам более знакомо, оно похоже на var currentTitle. Свойство display — это свойство нашего Controller или переменная экземпляра класса (instance variable), если вы хотите думать таким образом. Свойство display имеет тип UILabel !. Что же здесь означает восклицательный ! знак? Я думал, что восклицательный  знак — это «развернутое» Optional, почему здесь-то оно присутствует? Здесь это не имеет смысла. Но фактически вы можете поставить здесь вопросительный ? знак, потому что восклицательный ! знак также означает Optional. Он означает тот же самый Optional, что и вопросительный ? знак.
Screen Shot 2016-04-25 at 5.57.59 PM

Я оставлю здесь вопросительный ? знак и продолжу работать над демонстрационным примером. Затем мы вернемся к нему и заменим его на восклицательный ! знак, чтобы показать, что он означает в этом контексте.  Но восклицательный ! знак и  вопросительный ? знак, оба, означают Optional при декларировании. Итак, у меня есть display.
Когда я касаюсь цифр на цифровой клавиатуре, я хочу, чтобы они добавлялись к тому, что уже есть на дисплее display. Давайте сделаем это, но вначале избавимся от печати на консоли. Нам не нужно этого больше делать.

Я создам другую локальную переменную, которая тоже будет константой, и это let. Я назову эту локальную переменную textCurrentlyInDisplay.

Screen Shot 2016-04-25 at 6.43.34 PM
Я хочу получить текст, который находится в настоящий момент на дисплее display. И сообщение, которое мы пошлем display, — text. Мы можем посмотреть это в документации.

Screen Shot 2016-04-25 at 10.23.08 PM
Это даст мне текст, который находится на дисплее. Это метод UILabel. Но тут же появляется ошибка. Ошибка состоит в том, что я должен «развернуть» display. Вы видите, что display является Optional меткой UILabel. Вы не можете послать сообщение text типу Optional, тип Optional не понимает сообщения text.

Screen Shot 2016-04-25 at 10.27.11 PM
UILabel понимает сообщение text, так что нам нужно получить ассоциированное значение display, которым является UILabel, и мы можем это сделать здесь с помощью восклицательного ! знака. И опять, заметьте, что Xcode предлагает исправить эту ошибку, я соглашаюсь исправить ошибку и ставлю в конце  восклицательный ! знак.

Screen Shot 2016-04-25 at 10.38.36 PM
Теперь это «развернутое» Optional UILabel, и я ему посылаю сообщение text. На самом деле text — это свойство, наподобие currentTitle, которое также является свойством, но свойство кнопки UIButton, а text — это свойство метки UILabel. Если мы используем option+click на свойстве text, то мы увидим, что var text является  Optional String.

Screen Shot 2016-04-25 at 10.50.35 PM

Почему? Потому что UILabel может быть не установленаtext в ней, может быть, не установлен.  Он также является Optional, как и currentTitle. Так что нам нужно и его «развернуть».

—————— 65-ая минута Лекции ——————

Screen Shot 2016-04-27 at 8.07.58 AM
Теперь у меня String. Мне кажется, что вы, как и я, устали от всех этих восклицательных ! знаков, и мы собираемся избавиться то них. Через несколько секунд, так что не беспокойтесь.

Но по-любому у меня теперь есть текущий текст дисплея display. И я могу написать следующий код:

Screen Shot 2016-04-27 at 8.16.47 AM

Заметим, что вы можете использовать «+» для конкатенации строк. Некоторые языки разрешают, некоторые — нет. Swift разрешает. Заметьте также, что, когда я устанавливаю значение Optional, помните? здесь text — это Optional  String, я могу установить его так, чтобы оно было String, что означает, по определению, установку Optional в значение «установлено» и использование его ассоциированного значения.

Screen Shot 2016-04-27 at 11.00.42 AM

Теперь давайте посмотрим, как я смогу установить это Optional в значение «не установлено» ? Кто-нибудь знает? Вы говорите, что нужно установить эту вещь в nil.

Screen Shot 2016-04-27 at 11.53.07 AM

Это ключевое слово, означает, что Optional  «не установлено«. Если мы таким образом установили этот text, то он будет пустым. Таким образом, когда вы устанавливаете Optional, то вы можете установить его либо в nil, либо в ассоциированное значение.

Screen Shot 2016-04-27 at 4.06.28 PM

Звучит хорошо. Давайте запустим приложение
Я надеюсь, что если мы будем нажимать кнопки с цифрами, то они начнут появляться на дисплее display в конце. Нажимаем «5» — появилась, «8», «9» — все появляется, но мне не нравится «0» в самом начале:

Screen Shot 2016-04-27 at 4.08.40 PM

Нуль «0» — так калькулятор не работает. Когда я нажимаю «5», то я начинаю печатать новое число. Нам необходимо избавиться от «0». Нам необходимо найти способ, с помощью которого мы сможем отслеживать, находимся ли мы в процессе набора числа или нет. Потому что, если мы находимся в середине набора числа, то мы добавляем цифры в конец display, а если нет, то мы просто заменяем все, что находится на дисплее display, на то, что мы печатаем. Поэтому я собираюсь добавить новую переменную, переменную экземпляра класса, новое свойство с именем userIsInTheMiddleOfTyping.

Screen Shot 2016-04-27 at 4.23.26 PM

Теперь вы смеетесь, потому что вам кажется, что это такое длинное имя и вам придется очень много раз печатать его снова и снова, но вам больше никогда не придется его печатать. Потому что Xcode всегда сам заканчивает слова вместо вас. Так что длинные имена, в действительности, хорошо. Вы можете выбрать более короткое имя, чем то, что оно могло бы выражать, но, как вы знаете из информатики, правильное именование — это прежде всего хорошо для того, кто читает ваш код. Поэтому наше новое свойство имеет имя userIsInTheMiddleOfTyping и тип Bool.

Screen Shot 2016-04-27 at 6.47.20 PM
Это не Optional Bool. Это просто Bool. Так что нет вопросительного ? знака. Оно просто либо true, либо false. Либо я нахожусь в середине набора числа, либо — нет.
Но как только я добавил тип Bool, я получил ошибку. Видите ошибку? Но почему она появилась в верхней части кода, ведь я там ничего не делал? Давайте посмотрим, что за ошибка?

Screen Shot 2016-04-27 at 6.52.31 PM

У класса ViewController нет инициализаторов. Вы будете делать ваше Домашнее Задание и у вас будет происходить то же самое, вы будете удивляться: «Что такое? Я ничего не сделал, просто напечатал переменную var?» Что означает эта ошибка? Мы получили с вами ошибку потому, что в Swift все свойства (properties), абсолютно каждое свойство, должно иметь начальное значение. Вам не разрешается иметь свойства, у которых нет начальных значений. Как мы дадим начальное значение этому Bool свойству?
Есть два способа. Один способ — это создание инициализатора, о чем, собственно, и говорит предупреждение. Но я не собираюсь говорить об инициализаторах раньше следующей недели. Я не могу этого сделать сейчас, потому что я еще не говорил об этом. Какой другой способ мы можем использовать?

Мы можем просто написать = false. Мы просто инициализируем наше свойство, и ошибка уйдет.

Screen Shot 2016-04-27 at 7.06.05 PM
Ура! У нас все получилось, но некоторые из вас могут сказать: «А как же насчет display? Мы не инициализировали это свойство?»

Screen Shot 2016-04-27 at 7.09.33 PM

Это потому, что с Optionals мы будем обращаться особым образом. Они всегда инициализируются автоматически со значением «не установлено«.

Screen Shot 2016-04-27 at 7.14.27 PM

Это происходит всегда, если у вас есть var, которая является Optional. Это имеет определенный смысл:  у вас есть  Optional и она будет «не установлена» до тех пор, пока вы ее не установите во что-то. Так что все Optionals начинают со значения «не установлено«. Именно поэтому считается, что у Optional всегда есть начальное значение:

Screen Shot 2016-04-27 at 7.20.01 PM

Еще я хочу спросить вас, нужно ли нам декларировать  : Bool?

Screen Shot 2016-04-27 at 7.23.06 PM

Нет. Почему нам это не нужно? Потому что значение false может быть только у Bool, так что Swift сможет «вывести тип из контекста» (infer) и установить, что это тип Bool. Видите?

Screen Shot 2016-04-27 at 7.27.19 PM
Теперь давайте использовать userIsInTheMiddleOfTyping, и именно с этим свойством мы можем накапливать цифры на дисплее display или начинать все сначала. Мы будем использовать if предложение.

—————— 70-ая минута Лекции ——————

Screen Shot 2016-04-27 at 7.31.32 PM
Если пользователь находится в середине набора числа, то мы будем накапливать цифры, если нет, то мы устанавливаем на дисплее display напечатанную цифру. Если я начинаю печатать «5» или что-то еще, то это полностью заменит все, что было на дисплее display до этого. И, конечно, в любом случае мы должны установить userIsInTheMiddleOfTyping в true, потому что как только мы коснулись цифры digit, мы уже находимся в середине набора числа.

Screen Shot 2016-04-27 at 7.42.12 PM
Теперь я уже порядком устал от печатания каждый раз display с восклицательным ! знаком. Каждый раз, когда я печатаю display с восклицательным ! знаком, я, фактически, точно знаю, что  display всегда «установлен«. Единственный раз, когда он «не установлен» и длится это наносекунду, это когда он начинает появляться на экране, перед тем, как у iOS появляется шанс «подвязать» его к нашей метке UILabel. Но как только он «подвязан», он «установлен» навсегда. И, конечно, когда пользователь касается кнопок с цифрами, пользовательский интерфейс (UI) полностью находится на экране, все «подвязано» и я точно знаю, что display никогда не будет равен nil. Никогда в этом коде. Так почему же я продолжаю снова и снова набирать display с восклицательным ! знаком? Ответ заключается в том, что мы не должны этого делать, потому что мы вернемся назад и заменим вопросительный ? знак восклицательным ! знаком.

Screen Shot 2016-04-27 at 7.57.16 PM
Если вы разместили восклицательный ! знак при декларировании, то это говорит о том, что любой может использовать это свойство и оно будет «неявно развернуто» (implicitly unwrap). Оно будет автоматически «разворачиваться». Но если оно разворачивается, когда оно равно nil, то происходит аварийное завершение приложения. Итак, это позволяет мне избавиться от всех  восклицательных ! знаков, потому что при декларировании вместо вопросительного ? знака я разместил восклицательный ! знак.

Screen Shot 2016-04-27 at 8.20.26 PM

Все это поняли?

И опять, если я вернусь назад и восстановлю вопросительный ? знак при декларировании, то я получу ошибки, потому что я «не развернул» Optional,

Screen Shot 2016-04-27 at 8.09.18 PM

но, если я опять помещу восклицательный ! знак при декларировании, то теперь декларируемое свойство везде является «неявно развернутым» (implicitly unwrapping). Это называется implicitly unwrap Optional (неявно развернутое Optional). Это очень важно.

Screen Shot 2016-04-27 at 8.20.26 PM

Теперь запустим приложение и посмотрим, исправились ли наши ошибки?

Нажимаем «5» — избавились от нуля. Все работает.

Screen Shot 2016-04-27 at 8.24.27 PM
Мы проделали прекрасную работу и наша цифровая клавиатура полностью функционирует.

Теперь нам нужно добавить операции. Из-за ограниченного времени я добавлю только кнопку с ?. Это очень простая операция, которая заключается в том, что на дисплее display размещается  ?. Давайте сделаем это. Я собираюсь скопировать и вставить кнопку «7».

Screen Shot 2016-04-27 at 8.57.33 PM
В действительности, это очень плохая идея, и вы увидите это через секунду. Но я сделаю это и назову эту кнопку ?.

Screen Shot 2016-04-27 at 9.01.18 PM

Конечно, ? — это не цифра. Это операция и я выполню CTRL-перетягивание, чтобы создать новый другой Action, отличный от того, который был создан для цифр.

Screen Shot 2016-04-27 at 9.03.56 PM
Этот Action назовем performOperation, потому что  ? — это операция. Все кнопки с операциями будут иметь Action с именем performOperation.

Screen Shot 2016-04-27 at 9.08.49 PM

И не забудьте заменить AnyObject на UIButton, как и в вашем Домашнем Задании.

Screen Shot 2016-04-27 at 9.10.03 PM

Нажимаем кнопку Connect и получаем performOperation прямо здесь:

Screen Shot 2016-04-27 at 9.12.54 PM

В performOperation я сделаю то же самое, что я делал в начале метода touchDigit. Я спрошу sender, какую операцию он представляет?

Screen Shot 2016-04-28 at 8.25.03 AM

Конечно, мне нужна строка String и я ставлю восклицательный ! знак. Но если на кнопке пустой заголовок,

Screen Shot 2016-04-28 at 8.28.24 AM
я хотел бы игнорировать нажатие кнопки с такой операцией, вместо аварийного завершения приложения. А что, если вообще вполне законно иметь кнопку с пустым заголовком? Я хочу «разворачивать» только тогда, когда заголовок кнопки «установлен«. Способ, каким мы можем это сделать — не ставить восклицательный ! знак, а поставить в начале предложения  if. В этом случае хорошо, что не надо много печатать и выглядит так, как и читается. Если я могу выполнить присвоение
 let mathematicalSymbol = sender .currentTitle, то я могу что-то сделать в этом случае.

Screen Shot 2016-04-28 at 8.53.21 AM

Это хорошо читается по-английски и, действительно, прекрасный способ «развернуть» Optional. Внутри этого if, mathematicalSymbol будет строкой String.
Screen Shot 2016-04-28 at 8.57.17 AM
Это будет ассоциированное значение currentTitle. За пределами этого ifmathematicalSymbol даже не определено. Все супер просто.

Далее продолжим с mathematicalSymbol. Если mathematicalSymbol = ?, то я могу установить мой display, и я больше не использую восклицательный ! знак, в константу M_PI, которая является Double положительным значением ?.

Screen Shot 2016-04-28 at 9.08.49 AM
Теперь у нас появилась ошибка. Почему это ошибка появилась?

Screen Shot 2016-04-28 at 9.12.08 AM

Потому что нам говорят, что нельзя присвоить значение тип Double чему-то, что имеет тип String?. Мы знаем, что display.text является строкой  и имеет тип String?, следовательно, мы не должны делать такое присваивание. Как мы можем преобразовать Double в String? Ответ состоит в том, что мы должны создать новую строку. Сейчас вы увидите, как создается новый экземпляр объекта в Swift.

——————75-ая минута Лекции ——————

Для этого вы просто пишите имя класса, а затем круглые скобки, внутри которых вы размещаете все, что этот класс допускает при создании нового экземпляра. И у вас есть множество возможностей. Например, это могут быть инициализаторы, на которые мы ссылались раньше. К счастью, String в состоянии взять Double в качестве одной из таких вещей, так как она знает, как создать новую строку String из Double.

Screen Shot 2016-04-28 at 9.18.24 AM

Запускаем приложение, убеждаемся, что цифровая клавиатура работает и нажимаем кнопку ?.

Screen Shot 2016-04-28 at 9.32.04 AM
У нас проблема, так как не все цифры помещаются на нашем дисплее. Мы можем очень быстро это исправить. Вернемся обратно. В Инспекторе Атрибутов для нашего дисплея display есть замечательная «фишка» с именем Autoshrink, благодаря которой метка display будет автоматически «сжиматься», но не менее, чем до 9 point.

Screen Shot 2016-04-28 at 9.41.24 AM
Это решит нашу проблему.

Screen Shot 2016-04-28 at 9.46.57 AM
Но у нас есть еще одна проблема. Опять запускаем приложение и нажимаем  кнопку ?.

Screen Shot 2016-04-28 at 9.50.41 AM
Что это такое? В конце числа мы видим символ  ?.  Продолжаем нажимать цифры: «9», «6» и т.д..

Screen Shot 2016-04-28 at 9.53.42 AM

Это какой-то беспорядок. На самом деле у нас две проблемы здесь.

По некоторой причине, когда мы нажимаем кнопку ?, то в конце display появляется символ в конце. Почему? Это происходит по следующей причине. Смотрим на маленький кружочек слева

Screen Shot 2016-04-28 at 9.58.40 AM
Кнопка ? посылает Action performOperation. А как насчет Action touchDigit ?

Screen Shot 2016-04-28 at 10.01.27 AM
Кнопка ? также посылает и Action  touchDigit. Вы видите, что кнопка заставляет работать оба метода: и touchDigit, и performOperation. Это произошло потому, что я скопировал и вставил кнопку «7», которая посылает сообщение touchDigit и затем добавил еще одно — performOperation. Как нам исправить это? Для этого нужно на кнопке ? кликнуть правую кнопку мыши (или удерживая CTRL, просто кликнуть на мышке). Если вы кликните правую кнопку мыши на чем-нибудь из вашего UI, то вы увидите все связи этого элемента UI.

Screen Shot 2016-04-28 at 10.12.57 AM

Очень важно понимать, что происходит, если вы кликните правую кнопку мыши на вашем  UI. В случае с нашей  кнопкой ?, мы видим две связи: c touchDigit: и с performOperation: , так что я буду избавляться от связи touchDigit: . Для этого достаточно нажать на маленький крестик слева вверху touchDigit: .

Screen Shot 2016-04-28 at 10.19.39 AM

Теперь связь touchDigit: ушла и осталась только performOperation: .

Screen Shot 2016-04-28 at 10.20.50 AM

Эту проблему, связанную с размещение символа ?, мы решили. Но другая проблема пока осталась. Она заключается в том, что если я нажал кнопку ?,  а затем продолжаю печатать цифры, то приложение думает, что я нахожусь в середине набора числа, и добавляет печатаемые цифры в конец дисплея . Эту проблему исправить очень легко: я просто напишу

userIsInTheMiddleofTypingNumber = false

в методе performOperation, это сотрет все, что было на дисплее display до этого и, очевидно, теперь я не буду находиться в состоянии, когда я печатаю число.

Screen Shot 2016-04-28 at 10.22.49 AM
Теперь у нас есть полностью функционирующий калькулятор с одной операцией. Запускаем приложение. Набираем «4» «5» «?«

Screen Shot 2016-04-28 at 10.32.43 AM

В Среду мы сделаем более мощный калькулятор.

— Конец Лекции 1 ——

Лекция 1 CS193P Spring 2016 — Обзор курса и введение в iOS, Xcode и Swift. (часть 2): 35 комментариев

  1. Татьяна, огромное спасибо за ваши статьи! Реально помогают научиться азам программирования на Swift и познакомиться с экосистемой iOS…

  2. Татьяна, спасибо за Ваш труд!
    Благодаря Вашим переводам вышел на курсы Пола Хагерти, однако почти сразу перешел на текущий курс по iOS 9 Swift 2.2.
    Подскажите, уже есть тема для разбора домашних заданий по текущему курсу? Первое задание готово, хотелось его обсудить.
    Также могу предложить посильную помощь по переводам.

    • Спасибо. Мне очень нужна ваша помощь. Подробности сообщу по email в самое ближайшее время.

      • Хорошо!
        Кстати, всем советую обязательно читать reading assingnment по документации Apple, которая написана очень хорошо и доступно. Многие вопросы отпадают сами собой.

  3. Татьяна, спасибо больше за труд! Хотелось бы узнать будет ли продолжение и как скоро?

    • Сегодня или завтра выложу Лекцию 2. Намерена переводить все Лекции и выполнять все Задания, как и прошлый курс по iOS 8.

  4. Татьяна, скажите, я начинал предыдущий курс, потом оставил.. Есть смысл его завершать, чтобы приступить к этому? Или сразу начинать курс 2016?

    • Сразу начинайте курс 2016, потому что он читается для новой версии Swift 2.2 и с прицелом на Swift 3.0, а курс 2015 читался для Swift 1.0. Изменений произошло много. Кроме того, в курсе 2016 намного проще демонстрационный пример и Задания, связанные с Калькулятором. В курсе 2015 RPN калькулятор с рекурсией, и можно просто «потонуть» в особенностях его реализации в Задании 2. Но если вы любите сложные Задания, то это то, что надо. Но я бы не стала сбрасывать курс 2015 со счетов, потому что что-то, что было в курсе 2015, не будет представлено в курсе 2016. Если вы это обнаружите, то сможете вернуться к курсу 2015 и освоить этот недостающий материал.

  5. Спасибо ВАм огромное за проделанную работу. На ваш взгляд какой из трёх курсов более информативен в плане самой 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 он объясняет все и каждое его слово на вес золота.

  6. А верно ли я понял:

    @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 не установлено, то мы получим аварийное завершение программы.
            Позвольте мне уклониться от вопросов личного характера.

  7. Вот это титанический труд! Невероятно, что еще есть люди, которые способны безвозмездно проделать такой колоссальный обьем работы. Это удивительно! Огромное Вам спасибо за труды во благо других, кому это столь необходимо!!! Очень Вам благодарен!!!!

  8. XCode8.1 не совсем понял как вставить символ Пи ( заменил просто «Pi», копи-паста не работает — вместо символа знак «?» в кнопке). Спасибо в любом случае.

  9. Татьяна, у вас собраны шикарные материалы на сайте.
    Только верстка почему-то поехала — у меня на экране текст статьи отображается прям поверх картинок. (и не только в этой статье)

    • Меня предупредили, что 8 ноября ( 8pm MT) на bestkora.com проводится плановый переход на MySQL версии 5.6 для улучшения стабильности и безопасности. Возможно, вы попали на какой-то переходной период. Спасибо за предупреждение. Я буду следить за этим.

    • Да. Теперь вижу накладки картинок на текст. Это происходит только в Chrome, в Safari этих накладок нет. Буду с этим работать. Еще раз спасибо, что сообщили.

Обсуждение закрыто.