Главная
Блог разработчиков phpBB
 
+ 17 предустановленных модов
+ SEO-оптимизация форума
+ авторизация через соц. сети
+ защита от спама

Что нового в Objective-C и Foundation принесла iOS 7

Anna | 2.07.2014 | нет комментариев

Objective-C является особенно распространенным языком для разработки iOS и OS X приложений. Безусловно, дозволено применять сторонние фреймворки, которые разрешают разрабатывать приложения с применением других языков, таких как HTML и JavaScript либо C#, но если вы хотите написать немыслимо стремительно, результативные приложения, то вам необходимо применять Objective-C.

Foundation является одним из основных конструкций, которые вы будете применять при разработке приложений на языке Objective-C.

Как IOS разработчик, Вы обязаны быть в курсе востребованных и последних достижений в Objective-C и Foundation, в IOS 7 есть некоторые значимые метаморфозы которые необходимо знать.

В этой статье мы сделаем короткий обзор некоторых новых функций в Objective-C и Foundation.

Давайте начнем!

Модули / Modules

Огромна вероятность, что вы писали #import 1000 раз и больше:

#import <UIKit/UIKit.h><br>
#import <MapKit/MapKit.h><br>
#import <iAd/iAd.h><br>

Данный синтаксис возвращает нас к корням ObjectiveC: а именно к языку C. Содержание предварительноиэто Clang, личный C, C и Objective C компиляторы; а также LLDB — личный отладчик, тот, что является лучшим ином разработчика.

Новое решение: Модули

Первое публичное возникновение модулей в Objective-C было в докладе, сделанным Doug Gregor от Apple в 2012 году на собрании LLVM разработчиков. Это интересный разговор, и он настойчиво рекомендуется для всех, кто интересуется работой своих компиляторов. Вы можете обнаружить видео сессии в Интернете по адресу llvm.org/devmtg/2012-11/ # talk6.

Модули инкапсуляции конструкций во многих методах чище, чем когда-либо раньше. Огромнее препроцессору не нужно заменять #import директивы со каждому содержимым файла. Взамен этого, модуль обертывает framework в самостоятельный блок, тот, что заранее составлен таким же образом, как PCH файл и обеспечивает такое же совершенствование скорости компиляции. Тем не менее, вам огромнее не доводится констатировать framework тот, что вы используете в файле PCH, вы получите увеличение скорости легко с поддержкой модулей.

Но есть огромнее к модулям, чем легко это. Я уверен, что вы припомните бесчисленные шаги которые проходите, когда в 1-й раз вы используете новейший framework для приложений, это имеет тенденцию проходить приблизительно так:

  • Добавьте строку #import используемого framework.
  • Напишите код, тот, что использует framework.
  • Скомпилируете.
  • Посмотрите, от того что ошибки выложены во время соединения.
  • Помнить, что вы позабыли слинковать framework.
  • Добавьте framework к фазе сборки плана.
  • Скомпилировать вновь.

Немыслимо распространено позабыть слинковать framework, но модули также решают эту загвоздку старательно. (Есть ли что-нибудь, что не могут сделать модули? )

Модуль информирует компилятору не только, какие заголовочные файлы составляют модуль, но также и что спросы быть объединенными. Это оберегает от необходимости вручную линковать framework самосильно. Это — только крошечная вещь, но что-либо, что принуждает разработку разработывать проще, является отличной вещью!

Как применять модули

Модули Исключительно комфортны в Ваших планах. Для существующих планов первое, что необходимо сделать, включить их. Вы можете обнаружить эту опцию, ища modules в Build Settings Вашего плана (удостоверяющийся выбирать All, not Basic) и после этого изменить опции Enable Modules на YES, так как показанно ниже:

Все новые планы, сделанные в Xcode 5, проверка включена по умолчанию, но вы обязаны непременно включить его во всех существующих планов.

Link Frameworks Automatically эта опция может быть использована, Дабы включить либо отключить механическое связывание фреймворков, как это описано ранее. Есть немного причин, отчего вы хотите, отключить эту вероятность.

Как только модули включены, вы можете начать применять их в своем коде. Довально легко сделать это, впрочем есть одно малое метаморфоза в синтаксисе к которому вы так привыкли. Взамен обыкновенного синтаксиса # import, вы легко используете import:

@import UIKit;
@import MapKit;
@import iAd;

Все еще допустимо импортировать некоторые framework, которой Вам нужны. Как пример, если бы Вам необходимо было импортировать легко UIView, написали бы так:

@import UIKit.UIView;

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

Раньше, чем начнете приходить в фурор от модулей, есть тот немного протеста, к сожалению. С Xcode 5.0, не допустимо применять модули с Вашими собственными frameworks либо сторонними frameworks. Это, видимо, придет в свое время — но теперь это грустная сторона. Ничто не абсолютно – даже Objective C!

Новейший возвращаемый тип – instancetype

Новейший тип был добавлен в Objective-C, тот, что назвали — instancetype. Его дозволено только применяться в качестве возвращаемого типа способа Objective-C и применяется в качестве подсказки для компилятора, что возвращаемый тип способа будет экземпляром класса, которому принадлежит данный способ.

Примечание: Эта функция не является сурово новой для Xcode 5 и IOS 7, но была украдкой кинута в недавние сборки Clang. Тем не менее, Xcode 5 отмечана в 1-й раз, что Apple начал применять его на протяжении всех frameworks. Вы можете узнать огромнее об этой вероятности на официальном сайте Clang:clang.llvm.org/docs/LanguageExtensions.html Objective-C функциями.

Отчего instancetype пригодный? Разглядите дальнейший пример кода:

NSDictionary *d = [NSArray arrayWithObjects:@(1), @(2), nil];
NSLog(@"%i", d.count);

Правда это очевидно ненормально, компилятор не будет исторически делают безусловно ничего, Дабы известить Вам об ошибке. Испробуйте сами, если вы у Вас установлен Xcode 4.6. Вы подметите, что никакого предупреждения Вы не получите, правда в коде очевидно написано не правильно! Код будет трудиться даже без примечаний, так как и NSDictionary и экземпляры NSArray выведут число элементов.

Повод таких действий во время выполнения вследствие сильному, динамическому нраву Objective-C. Тип является чисто начальством компилятора. Способ count ищется во время выполнения в любом классе словарь переменной случается. В этом случае способ count существует, так что компилятор считает, что все будет отлично. Впрочем, это может возвратиться, Дабы укусить вас позднее, если вы добавили код, тот, что использует иной способ, тот, что NSArray не имеют всеобщего с NSDictionary, таких как objectAtIndex:. Вначале, это не будет ясно, где именно лежит вопрос.

Но отчего компилятор не узнать, что экземпляр возвращается [arrayWithObjects NSArray:] не является экземпляром NSDictionary? Ну, это потому, что его сигнатура способа заключается в дальнейшем:

  (id)arrayWithObjects:(id)firstObj, ...;

Обратите внимание на тип возвращаемого значения это ID. Тип ID это значение всякий Objective-C класс, он не обязаны быть даже подклассом NSObject. Он в буквальном смысле не имеет информации о типе, помимо того, это экземпляр Objective-C класса. Для этого, Дабы быть пригодным, компилятор выдает предупреждения, когда вы неявно приводите к ID для определенного типа, скажем NSDictionary * в приведенном выше примере. Если бы это выдавало предупреждение, идентификатор типа id был бы в существенной степени непотребным.

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

@interface MyArray : NSArray
@end

Сейчас разглядим применение вашего нового подкласса в коде ниже:

MyArray *array = [MyArray arrayWithObjects:@(1), @(2), nil];

Ах — сейчас вы видите, отчего возвращаемый тип arrayWithObjects: должен быть ID. Если бы это был NSArray *, то подклассы затребует, Дабы быть приведен к нужному классу. Это где новейший возвращаемый тип instancetype приходит внутри.

Если вы посмотрите на файл заголовка для NSArray в IOS 7.0 SDK, вы подметите, сигнатуры способа для этого способа изменилось на следующее:

  (instancetype)arrayWithObjects:(id)firstObj, ...;

Исключительная разница — тип возврата. Данный новейший тип возврата тот, что обеспечивает подсказку для компилятора, что возвращаемое значение будет экземпляром класса, к которому способу обращаются. Таким образом, когда arrayWithObjects: обращен NSArray, тип возврата выведен, Дабы быть NSArray *; если обращался к MyArray, тип возврата выведен, Дабы быть MyArray * и т.д.

Это работает по каждому задача с идентификатор типа id при поддержании вероятности поделить на подклассы удачно. Если скомпилируете начальный код в Xcode 5, вы сейчас увидите следующее предупреждение:

warning: incompatible pointer types initializing 'NSDictionary *' with an expression of type 'NSArray *' [-Wincompatible-pointer-types] NSDictionary *d = [NSArray arrayWithObjects:@(1), @(2), nil]; ^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

w00t — сейчас это пригодно! Сейчас Вы имеете вероятность решить задачу раньше, чем это превратится в катастрофический отказ позднее по коду.

Инициализаторы — также кандидаты на применение этого нового типа возврата. Компилятор предуприждал Вас течение некоторого времени, сейчас если устанавливаете тип возврата инициализатора к тому из несовместимого типа. Но по-видимому это легко неявно преобразовывает тип возврата идентификатора в instancetype под капотом. Обязаны все еще применять instancetype для инициализаторов, правда, потому что отменнее быть очевидным для пользы повадки.

Тяготитесь применять instancetype как дозволено огромнее; это стало эталоном для Apple — и никогда не знаете, когда это сохранит некоторое болезненное время для отладки.

Новейший Foundations

Оставшаяся часть этой статьи посвящена разным новым частям и функциям в Foundation, базовая основа всех Objective-C разработчиков. Сложно разрабатывать Objective-C приложений без Foundation, так как все IOS приложения требует ее применения. Поиск новых драгоценных камней в Foundation является огромный частью удовольствия от приобретения на руки нового выпуска IOS SDK!

Одним из основных усовершенствований в этой версии Foundation заключается в сетях; так много, на самом деле, что есть целая глава, посвященная в учебнику по IOS 7. Это дюже значимые вещи, так что мы собираемся выпустить сокращенный вариант главы позднее в IOS 7 Feast, Дабы подмогнуть каждому добираться до скорости с ним.

Дальше в этом разделе описываются другие увлекательные дополнения и метаморфозы в Foundation.

NSArray

Попытка получить объект от экземпляра NSArray выдаст исключение, если индекс, тот, что предоставляете, будет вне длины массива. Будете также Зачастую находить надобность получить доступ к первым и последним объектам массива, такой как тогда, когда используете непостоянный массив, Дабы содержать очередь. В первым прибыл — первым убыл (FIFO) очереди выталкиваете объекты от передней стороны массива, и в первым пришел — последним вышел (FILO) выталкиваете объекты от конца массива.

Впрочем, когда получаете первые либо последние объекты от массива, обязаны неизменно убедиться, что не переходите к чтению мимо конца массива, тот, что мог легко случиться, если бы массив был пуст. Это приводит к огромному числу изнурительного кода, Дабы обеспечить вызов к objectAtIndex: не будет выдавать исключение, как так:

NSMutableArray *queue = [NSMutableArray new];

// ...

if (queue.count > 0) {
    id firstObject = [queue objectAtIndex:0];
    // Use firstObject
}

// ...

if (queue.count > 0) {
    id lastObject = [queue objectAtIndex:(queue.count - 1)];
    // Use lastObject
}

В случае приобретения последнего объекта неизменно имели опцию применения дальнейшего способа NSArray:

- (id)lastObject;

Всякий в мире разработчики Objective-C — не сомненно будет рад, что впервой у него есть доступ к равнозначному способу, Дабы получить 1-й объект массива:

- (id)firstObject;

Данный цельный примитивный способ оказывается Исключительно пригодным. Вам огромнее не необходимо составлять массив, тот, что являющийся пустым. Если вы когда-либо сталкивались с падениями из-за исключения из границ, то вы непременно полюбите это славное дополнение.

Примечание: Если вы наблюдательно посмотрите на заголовок NSArray вы увидите, что на самом деле способ firstObject был приблизительно с IOS 4.0, но он не был опубликован даже до IOS 7. Следственно вы могли бы получить способ до IOS 7, но это затребовало бы объявить селектор firstObject в одном из ваших собственных файлов заголовка, Дабы осведомить компилятору, что она на самом деле существует. Такой подход безусловно не рекомендуется, так что это отлично, что Apple, наконец принес его из сокрытия.

Предшествующий фрагменте кода сейчас может быть переписан с применением этих 2-х способов и вы можете отказаться от длинной проверки, как показано ниже:

NSMutableArray *queue = [NSMutableArray new];
// ...

id firstObject = [queue firstObject];
// Use firstObject

id lastObject = [queue lastObject];
// Use lastObjec

NSData

Data — одна из тех пророческой, с которыми Вы имеете дело всякий день, когда программируете. NSData — Капитальный класс, тот, что инкапсулирует необработанные байты и обеспечивает способы для того, Дабы Вы управляли этими байтами, также читая и записывали данные в файл. Но одной дюже всеобщей задачей, для которой не было никакой собственной реализации, является кодирование и декодирование Base64. По крайней мере, это имело место до выпуска iOS 7

Base64 — группа схем кодирования двоичного файла к тексту, которые представляют двоичных данных в формате ASCII. Эти схемы обыкновенно применяются, где есть надобность закодировать двоичных данных, которые будут сохранены на либо переданы по носителям, разработанным, Дабы иметь дело экстраординарно с текстовыми данными. Это убедилось, что данные остаются неповрежденными без модификации во время транспорта. Особенно знаменитый метод применения кодирования Base64 обрабатывает присоединения в электронном письме, а также кодирует маленькие изображения, которые являются частью результата JSON, возвращенного веб-API.

До iOS 7.0, Base64 кодирующие и декодирующие задачи затребовали, Дабы реализовали свой личный способ либо включали часть сторонней платформы. Классическим методом Apple это сейчас дюже комфортно эта функциональность. Дальнейшим образом есть четыре базовых способа Base64:

- (id)initWithBase64EncodedString:(NSString *)base64String 
      options:(NSDataBase64DecodingOptions)options;

- (NSString *)base64EncodedStringWithOptions:
      (NSDataBase64EncodingOptions)options;

- (id)initWithBase64EncodedData:(NSData *)base64Data 
      options:(NSDataBase64DecodingOptions)options;

- (NSData *)base64EncodedDataWithOptions:
      (NSDataBase64EncodingOptions)options;

Первые два способа имеют дело со строками, в то время как последние два имеют дело с закодированными данными UTF-8. Обе пары способов исполняют то же действие, но изредка применение того либо другого окажется больше результативным. Если были к Base64, кодируют строку и после этого пишут ее в файл, можете решить применять пару, которая обрабатывает закодированные данные UTF-8. С иной стороны, если были к Base64, кодируют строку и после этого применяют это в некотором JSON, можете решить применять пару, которая обрабатывает строки.

Таким образом, если когда-либо успользовали два способа Base64 в Вашем плане, сейчас время, Дабы удалить тот непотребный код и применять реализацию Apple взамен Вашего кода!

NSTimer

Таймеры Зачастую находят применение в приложения, которые исполняют периодические задачи. Столь пригодный, как они могут быть, задача состоит в том, что они могут непрерывно применять, когда несколько таймеров применяются. Это обозначает, что ЦП непрерывно энергичен; было бы гораздо больше результативно, если бы ЦП проснулся, исполнил пакет задач и после этого возвратился ко сну. Дабы решить эту загвоздку, Apple добавил качество допуска к NSTimer, Дабы подмогнуть адаптироваться к этому поведение.

Качество допуска предоставляет системе начальство касательно того, как поздно таймеру разрешают стрелять позже того, как это — время расписания. Базовая система будет тогда действия группы соответственно, Дабы уменьшить издержки ЦП. Способы для того, Дабы получить доступ к этому новому свойству следующие:

- (NSTimeInterval)tolerance;
- (void)setTolerance:(NSTimeInterval)tolerance;

Можете обнаружить, что никогда не обязаны применять это качество, но если запускаете несколько таймеров в дюже близкую последовательность, можете счесть пригодным протестировать применения ЦП Вашего приложения в сопоставлении с стандартом, применяя Instruments при переделывания этой установки.

NSProgress

Не так Зачастую, что всецело новые классы добавлены к Foundation. Это — достаточно устойчивая платформа, основным образом потому что новые базовые классы не требуются слишком Зачастую. Впрочем, iOS 7.0 приносит всецело новейший класс под наименованием NSProgress.

В основном NSProgress тяготится обеспечивать прогресс, уведомляющий везде по коду Objective C, старательно разделяя прогресс отдельных компонентов. Скажем, если исполняете несколько разных задач на некоторых данных, тогда всякая задача может контролировать свой личный прогресс и известить его родительской задаче.

Конструкция NSProgress

Самый легкой метод применять NSProgress состоит в том, Дабы применять его, Дабы известить о достижениях по ряду задач. Скажем, если Вы имеете 10 задач завершонных, после этого можете известить о прогрессе, от того что всякая задача завершается. От того что всякая задача завершается, прогресс восстанавливает работоспособность на 10%. После этого применяя Key Value Observing (KVO) экземпляра NSProgress, будете уведомлены об этом протекающем увеличении. Могли бы применять это уведомление в качестве вероятности обновить индикатор выполнения либо установить текст на метке, Дабы дать информацию касательно прогресса.

Но есть огромнее к NSProgress, чем легко это. Apple сделал его немыслимо сильным, основным образом с поддержкой дочерней родительской конструкции отношения. Конструкция NSProgress во многом как вложенное дерево: у всякого экземпляра могут быть один родитель и много дочерних элементов. У всякого экземпляра есть всеобщее число единиц работы, которые будут выполняться, и в то время как задача развивается, законченное число модулей обновлено, Дабы отразить нынешнее состояние. При этом родитель (если существуете) уведомлен касательно прогресса также.

Дабы уменьшить надобность раздать экземпляры NSProgress, у всякого потока есть свой личный экземпляр NSProgress, и дочерние экземпляры могут быть сделаны непринужденно из этого экземпляра. Без этой функциональности всякая задача, которая требовала осведомить о прогрессе таким образом, должна будет быть изменена, Дабы взять параметр NSProgress.

Создание отчетов о прогрессе

Применение NSProgress легко. Все начинается со дальнейшего способа:

  (NSProgress *)progressWithTotalUnitCount:(int64_t)unitCount;

Это создает новейший экземпляр NSProgress как дочерний элемент нынешнего экземпляра и инициализирует его с всеобщим числом единиц работы, которые будут выполняться в целом. Скажем, если бы задача состояла в том, Дабы циклично пройти через массив, то, возможно, инициализировали бы экземпляр NSProgress с числом массива, как так:

NSArray *array = /* ... */;

NSProgress *progress = 
    [NSProgress progressWithTotalUnitCount:array.count];

[array enumerateObjectsUsingBlock:
    ^(id obj, NSUInteger idx, BOOL *stop) {
        // Perform an expensive operation on obj
        progress.completedUnitCount = idx;
    }];

В то время как итерация развивается, вышеупомянутый код обновляет экземпляр NSProgress, Дабы отразить нынешний прогресс.

Приобретение обновлений прогресса

Вы можете определить прогресс задачи в всякий точке, через следующее качество:

@property (readonly) double fractionCompleted;

Это возвращает значение от 0 до 1, указывая всеобщий прогресс задачи. Когда нет никаких дочерних экземпляров в игре, fractionCompleted — легко законченное число модуля, поделенное на всеобщее число модуля.

Key Value Observing (KVO) — наилучший путь, тот, что будет уведомлен, когда качество fractionCompleted изменяет свое значение. Выполнение так легко. Все, что обязаны сделать, зарегистрироваться как наблюдатель fractionCompleted свойства соответствующего объекта NSProgress так:

[_progress addObserver:self 
            forKeyPath:@"fractionCompleted" 
               options:NSKeyValueObservingOptionNew 
               context:NULL];

После этого переопределите способ для применение KVO, Дабы уведомить касательно изменений, так:

- (void)observeValueForKeyPath:(NSString *)keyPath 
                      ofObject:(id)object 
                        change:(NSDictionary *)change 
                       context:(void *)context
{
    if (object == _progress) {
        // Handle new fractionCompleted value
        return;
    }

    // Always call super, incase it uses KVO also
    [super observeValueForKeyPath:keyPath 
                         ofObject:object 
                           change:change 
                          context:context];
}

В этом способе обработали бы метаморфоза значения fractionCompleted. Скажем, могли бы изменить значение индикатора выполнения либо метки, Дабы указать нынешний ярус заключения.

Безусловно, это значимо помнить, Дабы удалить из KVO как только вы завершите, вот так:

[_progress removeObserver:self forKeyPath:@"fractionCompleted" context:NULL];

Вы неизменно обязаны отменить регистрацию и Ваше приложение либо оно упадет, если вы не отмените регистрацию к тому времени, зарегистрированного объекта (Self в данном примере), будет освобожден. Следственно нужно удостовериться, что вы отмените регистрацию в качестве последнего средства в dealloc если это нужно.

p.s. Попрошу сурово не судить, если допустимо то примечания пишите в личку, подправим. Спасибо за осознавание.

Источник: programmingmaster.ru

Оставить комментарий
Форум phpBB, русская поддержка форума phpBB
Рейтинг@Mail.ru 2008 - 2017 © BB3x.ru - русская поддержка форума phpBB