Samond Classes Library 1.2.6-STABLE build 219
Руководство программиста

Оглавление

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

Список разделов руководства:


Введение

Библиотека Samond Classed Library представляет собой набор протоколов, классов и категорий, объединенных друг с другом для решения следующих основных задач:

В следующих разделах мы рассмотрим различные вопросы использования тех или иных компонентов библиотеки. Процесс изучения моих разработок мы будем сопровождать различными примерами.

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


Общие элементы классов

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

Реализация данных протоколов обеспечивается в следующих структурах:


Категория NSObject(SCObject)

Категория NSObject(SCObject) обеспечивает реализацию вышеприведенных протоколов, обеспечивая тем самым поддержку функционала библиотеки всеми классами, которые являются потомками класса NSObject. Благодаря этому при создании потомков класса NSObject и категорий его существующих дочерних классов избавляет от необходимости новой реализации протоколов - достаточно переопределить только минимально необходимые методы.


Класс SCObject

Все модули библиотеки (за исключением расширяющих функциональность стандартных классов категорий, а также классов исключительных ситуаций) являются потомками общего класса-предка SCObject. Начиная с версии 1.2.1 данный класс применяется в целях группировки собственных классов библиотеки, а в предыдущих версиях класс обеспечивал реализацию основных протоколов, которая теперь реализована в категории NSObject(SCObject).

Класс обеспечивает доступ к следующим функциональным возможностям:


Определение имен классов

Общие механизмы библиотеки для идентификации экземпляров классов используют свойство, которое в основных протоколах объявлено следующим образом:

@property (nonatomic, readonly, copy) NSString *className;

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

При создании собственных потомков классов NSObject и SCObject необходимо переопределение данного метода. Также определение данного метода необходимо при расширении уже существующих классов (как стандартных, так и из состава сторонних библиотек).


Поддержка последовательных файлов и протокол SCCoding

Стандартные библиотеки Objective-C предоставляют в распоряжение программистов возможности по чтению и записи последовательных файлов (особая форма списков параметров plist). Для поддержки данных возможностей протокол SCCoding (является наследником стандартного протокола NSCoding) объявляет следующие методы:

- (instancetype)initWithContentsOfSerializedFile:(NSString *)path;
- (BOOL)writeContentsToSerializedFile:(NSString *)path;

От стандартного протокола NSCoding протокол SCCoding наследует методы для взаимодействия со стандартными кодировщиками (NSCoder):

- (instancetype)initWithCoder:(NSCoder *)coder;
- (void)encodeWithCoder:(NSCoder *)coder;

Данные методы подлежат перекрытию в дочерних классах при наличии в них собственных полей данных. Если дочерний класс таковых не содержит, а только объявляет новые или перекрывает существующие методы, необходимости переопределения данных методов нет.

Подробнее с работой последовательных файлов Вы можете ознакомиться в разделе руководства Взаимодействие с последовательными файлами.


Поддержка словарей и протокол SCDictionaring

Стандартные классы NSDictionary и NSMutableDictionary обеспечивают возможности хранения информации в виде списков параметров plist. Данный способ хранения используется нашей библиотекой как один из способов сохранения данных экземпляров классов.

Протокол SCDictionaring объявляет необходимыми к реализации следующие методы:

- (instancetype)initWithDataDictionary:(NSDictionary *)dictionary;
- (instancetype)initWithDataDictionaryFromFile:(NSString *)path;
- (void)writeToDataDictionary:(NSMutableDictionary *)dictionary;
- (void)writeToDataDictionaryFile:(NSString *)path atomically:(BOOL)atomically;
- (void)writeToDataDictionaryFile:(NSString *)path;
- (NSDictionary *)dataDictionary;

Если дочерний класс содержит собственные данные, то необходимо переопределять методы initWithDataDictionary: и writeToDataDictionary:.

Работа со словарями подробно описана в соответствующем разделе данного руководства.


Поддержка потоков и протокол SCStreaming

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

Необходимые для взаимодействия с потоками методы объявлены в протоколе SCStreaming:

- (instancetype)initWithStream:(SCStream *)stream;
- (instancetype)initWithFileStream:(NSString *)path;
- (void)writeToStream:(SCStream *)stream;
- (void)writeToFileStream:(NSString *)path;
- (void)appendToFileStream:(NSString *)path;

Методы initWithStream: и writeToStream: должны быть перекрыты при наличии в дочерних классах собственных данных.

Подробности работы с потоками описаны в разделе Потоки.


Поддержка коллекций и протокол SCCollectioning

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

- (id)copyObject;
- (SCComparisonResult)compareWithObject:(id<SCCollectioning>)object;

Метод compareWithObject: возвращает одно из следующих значений:

SCComparisonEqual - экземпляры классов равнозначны
SCComparisonLess - первый объект меньше второго объекта
SCComparisonGreater - первый объект больше второго объекта
SCComparisonNotAllowed - объекты не могут сравниваться друг с другом

Описание работы механизма коллекций приводится в соответствующем разделе документации.


Взаимодействие с объектами данных

Объекты данных представляют собой экземпляры классов NSData и NSMutableData, которые обеспечивают хранение различных данных в виде нетипизированной последовательности байтов. Для взаимодействия с ними, а также для работы со связанными с объектами данных файлами и URL класс SCObject реализует следующие методы протокола SCDating:

- (instancetype)initWithData:(NSData *)data;
- (instancetype)initWithDataWrapper:(SCData *)data;
- (instancetype)initWithContentsOfFile:(NSString *)path;
- (instancetype)initWithContentsOfURL:(NSURL *)url;
- (instancetype)initWithContentsOfURLString:(NSString *)urlString;
- (void)writeToData:(NSMutableData *)data;
- (BOOL)writeToFile:(NSString *)path;
- (BOOL)writeToURL:(NSURL *)url;
- (BOOL)writeToURLString:(NSString *)urlString;
- (NSData *)data;

Подробное описание методов взаимодействия с объектами данных приведено в соответствующем разделе руководства.


Функциональность библиотеки и стандартные классы

Как было отмечено выше, при работе с потомками класса SCObject для взаимодействия с различными механизмами библиотеки необходимо переопределять только часть методов.

Однако при реализации функционала в расширяющих стандартные классы категориях реализации подлежат все методы соответствующих протоколов.


Взаимодействие с последовательными файлами

Последовательные файлы (serialized files) представляют собой специальную версию файлов свойств (property list - plist), которые позволяют в текстовых файлах XML хранить различные данные. При этом для чтения и записи используются кодировщики на базе стандартного класса NSCoder.

Основная функциональность работы с последовательными файлами реализована в стандартном протоколе NSCoding. SCL расширяет данную функциональность прежде всего в целях приведения ее к общему с остальными механизмами формату.

Данный раздел руководства описывает приемы и методы работы с последовательными файлами. Требования к классам изложены в разделе Поддержка последовательных файлов и протокол SCCoding. Отметим, что главное требование - соответствие класса протоколу SCCoding.

Содержимое раздела:


Сохранение экземпляров класса

Запись в последовательный файл осуществляется с помощью метода writeContentsToSerializedFile:, в качестве параметра которого указывается путь к последовательному файлу. Если операция записи прошла успешно, метод возвращает значение YES, в противном случае возвращается значение NO. Если последовательный файл уже существует, то его содержимое уничтожается.

NSString *sourceString = @"Sample source string";
if ( [sourceString writeContentsToSerializedFile:@"/tmp/serial.plist"]) {
NSLog( @"Writing complited");
} else {
NSLog( @"Writing error");
}
2016-06-17 02:24:14.644 libtest[14033:493323] Writing complited

Получившийся в результате исполнения примера последовательный файл:

sample_03_01.png

Загрузка экземпляров класса

Инициализация экземпляра класса на основании данных из последовательного файла выполняется с помощью метода initWithContentsOfSerializedFile:, которому в качестве параметра передается путь к последовательному файлу.

NSString *string = [[NSString alloc] initWithContentsOfSerializedFile:@"/tmp/serial.plist"];
NSLog( @"%@", string);
2016-06-17 02:57:16.339 libtest[14308:521945] Sample source string

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

+ (SCArray *)arrayWithCoder:(NSCoder *)coder;
+ (SCArray *)arrayWithContentsOfSerializedFile:(NSString *)path;

Работа со словарями

Словари на базе стандартных классов NSDictionary и NSMutableDictionary обеспечивают доступ к универсальным хранилищам данных, работающим по принципу "ключ-значение", согласно которому доступ к хранимым данным осуществляется посредством ключей, в качестве которых могут выступать экземпляры любых объектов Objective-C.

Словари напрямую связаны со списками свойств (property list). Благодаря этому в распоряжении программистов оказываются не только простые средства по организации универсальных хранилищ, но и возможности по контролю и редактированию этих хранилищ - встроенный в Xcode редактор списков свойств обеспечивает удобный доступ к данным.

Со словарями могут взаимодействовать экземпляры классов, которые соответствуют протоколу SCDictionaring. Описание реализации данного протокола приведено в разделе Поддержка словарей и протокол SCDictionaring.

Содержимое раздела:


Запись в словарь

Основным методом для записи данных в словарь является метод writeToDataDictionary:, которому в качестве параметра передается изменяемый словарь (класс NSMutableDictionary), в который и производится запись данных экземпляра класса. Именно этот метод подлежит перекрытию в дочерних классах при необходимости сохранять в словарях отличные от класса-предка данные.

Приведем пример сохранения в словаре экземпляра класса SCDictionary:

SCDictionary *sourceDictionary = [SCDictionary dictionaryWithName:@"Configuration"];
[sourceDictionary setObject:@"MacOS" forKey:@"System"];
[sourceDictionary setObject:@NO forKey:@"Verbose"];
[sourceDictionary setObject:@2319 forKey:@"Build"];
[sourceDictionary setObject:[NSDate date] forKey:@"Startup"];
NSMutableDictionary *dictionary = [NSMutableDictionary dictionary];
[sourceDictionary writeToDataDictionary:dictionary];
NSLog( @"%@", dictionary);
2017-09-10 10:43:29.416454+0300 libtest[13324:1085938] {
"Read Only" = 0;
"Item 3" = {
Key = {
OBJC_ClassName = NSString;
String = System
};
Object = {
OBJC_ClassName = NSString;
String = MacOS
}
};
"Item 0" = {
Key = {
OBJC_ClassName = NSString;
String = Build
};
Object = {
OBJC_ClassName = NSNumber;
Number = 2319
}
};
"Item 1" = {
Key = {
OBJC_ClassName = NSString;
String = Verbose
};
Object = {
OBJC_ClassName = NSNumber;
Number = 0
}
};
"Item 2" = {
Key = {
OBJC_ClassName = NSString;
String = Startup
};
Object = {
OBJC_ClassName = NSDate;
Date = "2017-09-10 07:43:29 +0000"
}
};
OBJC_ClassName = SCDictionary;
Name = Configuration
}

Свойство dataDictionary возвращает словарь с данными экземпляра класса:

NSString *sourceString = @"Sample UTF-8 string";
NSLog( @"%@", sourceString.dataDictionary);
2016-06-17 04:25:17.156 libtest[14713:582644] {
"OBJC_ClassName" = NSString;
String = "Sample UTF-8 string";
}

Запись экземпляра класса в файл свойств осуществляется следующими методами:

- (void)writeToDataDictionaryFile:(NSString *)path atomically:(BOOL)atomically;
- (void)writeToDataDictionaryFile:(NSString *)path;

Оба метода в качестве аргумента принимают путь к файлу. Если данный файл существует, его содержимое уничтожается. Разница между ними в том, что у первого из них параметр atomically: позволяет указать, будет ли запись в файл производиться непосредственно (NO) или через промежуточный файл (YES). Второй метод всегда осуществляет запись через промежуточный файл.

SCDictionary *sourceDictionary = [SCDictionary dictionaryWithName:@"Configuration"];
[sourceDictionary setObject:@"MacOS" forKey:@"System"];
[sourceDictionary setObject:@NO forKey:@"Verbose"];
[sourceDictionary setObject:@2319 forKey:@"Build"];
[sourceDictionary setObject:[NSDate date] forKey:@"Startup"];
[sourceDictionary writeToDataDictionaryFile:@"/tmp/data.plist"];

После выполнения данного кода создается файл со следующим содержимым:

sample_03_02.png

Начиная с версии 1.2.5 в класс NSMutableDictionary добавлен следующий метод:

- (void)addObject:(id<SCDictionaring>)object forKey:(NSString *)key;

Данный метод сохраняет указанный объект вместе с ключем в формате словарей данных. Использование данного метода вместо стандартного метода setObject:forKey: гарантирует, что объект и его ключ будут сохранены в файле словаря вне зависимости от их типа - стандартный словарь поддерживает запись в файл словаря ограниченное количество типов объектов, а в качестве ключей в файлы словарей успешно записываются только ключи типа NSString.


Чтение из словаря

Для загрузки экзепляров классов из словарей и файлов свойств применяются следующие методы:

- (instancetype)initWithDataDictionary:(NSDictionary *)dictionary;
- (instancetype)initWithDataDictionaryFromFile:(NSString *)path;

Метод initWithDataDictionary: инициализирует экземпляр класса из указанного в качестве аргумента словаря. Путем перекрытия данного метода осуществляется добавление в дочерние классы поддержки загрузки из словарей их собственных данных.

С помощью метода initWithDataDictionaryFromFile: осуществляется инициализация экземпляра класса из файла свойств с путем к нему в качестве аргумента метода.

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

+ (SCQueue *)queueWithDataDictionary:(NSDictionary *)dictionary;
+ (SCQueue *)queueWithDataDictionaryFromFile:(NSString *)path;

Начиная с версии 1.2.5 в дополнение к стандартному методу objectForKey: в класс NSDictionary добавлен метод:

- (id)getObjectForKey:(NSString *)key;

Данный метод создает и возвращает объект с заданным ключем, который ранее был сохранен в формате словарей данных. Этот метод обеспечивает поддержку в файлах словарей всех типов объектов и ключей, а не только тех, которые по умолчанию поддерживаются классами NSDictionary и NSMutableDictionary.


Потоки

Потоки представляют собой группу классов, которые реализуют концепцию байт-ориентированных средств ввода-вывода информации. Согласно данной концепции, потоки осуществляю ввод и вывод данных без какой-либо обработки (за исключением работы с экземплярами классов и текстовых строк - их обработка является частью механизма потоков).

Содержимое раздела:


Иерархия классов потоков

streams.png

Общим предком всех классов потоков является класс SCStream, который определяет все механизмы работы потоков, за исключением непосредственно операций ввода и вывода - предназначенные для осуществления данных операций методы в классе SCStream являются абстрактными.

Дочерние классы в обязательном порядке переопределяют методы операций ввода и вывода, а при необходимости дополняют методы, которые являются специфическими для конкретных видов потоков. Например, дочерний класс SCFileStream объявляет методы открытия и закрытия файловых потоков.

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


Обработка ошибок при работе с потоками

При работе с потоками могут возникать различные ошибки, связанные как непосредственно с потоками (или конкретными классами потоков), так и возникающие за пределами нашего кода, например при попытке записи в доступный только для чтения файл.

Режим обработки ошибок определяется через свойство errorHandling и может принимать одно из следующих значений:

По умолчанию используется режим, при котором генерируется исключительная ситуация SCStreamException.


Генерация исключительной ситуации SCSystemException

Режим включается через прямое или косвенное назначение свойству errorHandling значения SCStreamErrorHandlingSystem.

При использовании данного варианта ошибок механизм потоков генерирует исключительную ситуацию SCSystemException, которая содержит информацию об ошибке, которая была возвращена либо системным вызовом, либо вызовом стандартных библиотек. Основной информацией является свойство error, содержащее идентификатор возникшей системной ошибки. Более подробную информацию содержит раздел руководства программиста, посвященный исключительной ситуации SCSystemException.

Приведем пример использования данного способа обработки ошибок:

SCFileStream *stream = [[[SCFileStream alloc] init] autorelease];
[stream openReadOnlyWithPath:@"/tmp/error.txt"];
[stream close];
2016-07-05 23:01:53.322 libtest[5608:1486493] SCL-20002: No such file or directory (2, /tmp/error.txt)

Генерация исключительной ситуации SCStreamException

Режим включается через прямое или косвенное назначение свойству errorHandling значения SCStreamErrorHandlingStream.

Данный вариант обработки ошибок при их возникновении генерирует исключительную ситуацию SCStreamException, которая содержит информацию, помогающую определить причины возникновения ошибок. В отличие от класса SCSystemException, исключительная ситуация SCStreamException содержит информацию, специфическую именно для механизма потоков.

С помощью данной исключительной ситуации могут быть обработаны следующие ошибки при работе с потоками:

Приведем пример обработки ошибок потоков через генерацию исключительной ситуации SCStreamException:

[stream close];
2016-07-05 22:52:34.159 libtest[5534:1475780] SCL-20029: Stream "/tmp/start.txt" open error (2)

Изменение состояния потока

Режим включается через прямое или косвенное назначение свойству errorHandling значения SCStreamErrorHandlingStatus.

При использовании данного варианта обработки ошибок механизм потоков работает по следующему алгоритму:

Приведем пример обработки ошибок с помощью данного способа:

SCFileStream *stream = [[[SCFileStream alloc] init] autorelease];
[stream openReadOnlyWithPath:@"/tmp/error.txt"];
NSLog( @"Stream status: %d", stream.status);
[stream close];
2016-07-05 23:19:45.803 libtest[5678:1502988] Stream status: -20029

Определение состояния потока

Состояние потока определяется свойством:

@property (nonatomic, readonly, assign) SCStreamStatus status;

Непосредственно класс SCStream через тип SCStreamStatus определяет следующие состояния потоков:

Дочерние классы могут определять свои собственные производные типы состояний потоков. Например, класс SCFileStream определяет тип SCFileStreamStatus, расширяющий базовые коды состояний потоков. Подробности данного расширения описывается в соответствующем разделе руководства программиста.


Свойства потоков

Класс SCStream содержит объявление следующих свойств:

@property (nonatomic, readwrite, assign) SCStreamErrorHandling errorHandling;
@property (nonatomic, readonly, assign) SCStreamStatus status;
@property (nonatomic, readonly, retain) NSString *name;
@property (nonatomic, readonly, assign) BOOL opened;
@property (nonatomic, assign, readonly, getter=eof) BOOL eof;
@property (nonatomic, assign, getter=delegate, setter=setDelegate:) id<SCStreamDelegate> delegate;
@property (nonatomic, readonly, assign) BOOL readable;
@property (nonatomic, assign, readonly, getter=writable) BOOL writable;
@property (nonatomic, assign, readonly, getter=readOnly) BOOL readOnly;
@property (nonatomic, assign, readonly, getter=writeOnly) BOOL writeOnly;
@property (nonatomic, assign, readonly, getter=readWrite) BOOL readWrite;
@property (nonatomic, assign, readonly, getter=streamException) SCStreamException *streamException;
@property (nonatomic, assign, readonly, getter=systemException) SCSystemException *systemException;

Дочерние классы могут определять свои собственные свойства.


Чтение данных из потока

Основной метод чтения данных из потока объявлен в классе SCStream следующим образом:

- (SCSize)readBytes:(SCSize)count toBuffer:(void *)buffer;

Данный метод считывает из потока указанное количество символов в буфер с заданным указателем. В качестве значения метод возвращает количество реально считанных символов. В базовом классе SCStream метод является абстрактным и должен быть перекрыт во всех дочерних классах, поддерживающих операции чтения данных.

Кроме основного метода чтения класс SCStream определяет специализированные методы, обеспечивающие чтение в указанные буферы данных соответствующих типов. Фактически данные методы вызывают основной метод readBytes:toBuffer: со скрытым указанием количества символов, соответствующих данному типу. В качестве значения методы также возвращают количество реально считанных символов.

- (SCSize)readToByte:(SCByte *)buffer;
- (SCSize)readToUByte:(SCUByte *)buffer;
- (SCSize)readToShort:(SCShort *)buffer;
- (SCSize)readToUShort:(SCUShort *)buffer;
- (SCSize)readToInteger:(SCInteger *)buffer;
- (SCSize)readToUInteger:(SCUInteger *)buffer;
- (SCSize)readToLong:(SCULong *)buffer;
- (SCSize)readToULong:(SCULong *)buffer;
- (SCSize)readToChar:(char *)buffer;
- (SCSize)readToUnichar:(unichar *)buffer;
- (SCSize)readToCharString:(char *)buffer max:(SCSize)max;
- (SCSize)readToBool:(BOOL *)buffer;
- (SCSize)readToFloat:(SCFloat *)buffer;
- (SCSize)readToDouble:(SCDouble *)buffer;
- (SCSize)readToNSInteger:(NSInteger *)buffer;
- (SCSize)readToNSUInteger:(NSUInteger *)buffer;

Также в классе SCStream объявлены методы, которые возвращают считанные из потока данные соответствующих типов:

- (SCByte)readByte;
- (SCUByte)readUByte;
- (SCShort)readShort;
- (SCUShort)readUShort;
- (SCInteger)readInteger;
- (SCUInteger)readUInteger;
- (SCLong)readLong;
- (SCULong)readULong;
- (char)readChar;
- (unichar)readUnichar;
- (const char *)readCharString;
- (BOOL)readBool;
- (SCFloat)readFloat;
- (SCDouble)readDouble;
- (NSInteger)readNSInteger;
- (NSUInteger)readNSUInteger;

Обращаем внимание, что чтение данных из потока возможно только в том случае, если данный поток поддерживает операции чтения данных. В противном случае механизм потоков фиксирует ошибку.


Запись данных в поток

Класс SCStream объявляет следующий основной метод для записи данных в поток:

- (SCSize)writeBytes:(SCSize)count fromBuffer:(const void *)buffer;

Этот метод записывает в поток указанное количество символов из буфера с заданным указателем и возвращает количество реально записанных символов. Базовый класс SCStream содержит только абстрактное объявление данного метода, которое подлежит перекрытию в дочерних классах, которые поддерживают операции записи.

Для облегчения работы со стандартными типами данных класс SCStream объявляет методы записи в поток переменных таких типов.

- (void)writeByte:(SCByte)variable;
- (void)writeUByte:(SCUByte)variable;
- (void)writeShort:(SCShort)variable;
- (void)writeUShort:(SCUShort)variable;
- (void)writeInteger:(SCInteger)variable;
- (void)writeUInteger:(SCUInteger)variable;
- (void)writeLong:(SCLong)variable;
- (void)writeULong:(SCULong)variable;
- (void)writeChar:(char)variable;
- (void)writeUnichar:(unichar)variable;
- (void)writeCharString:(const char *)variable;
- (void)writeBool:(BOOL)variable;
- (void)writeFloat:(SCFloat)variable;
- (void)writeDouble:(SCDouble)variable;
- (void)writeNSInteger:(NSInteger)variable;
- (void)writeNSUInteger:(NSUInteger)variable;

Хочу обратить внимание, что запись данных в поток возможна только в том случае, если данный поток поддерживает операции записи. Если методы записи будут вызваны для потоков, не поддерживающих такие операции, механизм потоков зафиксирует ошибку.


Потоки и классы

Хотя в основе работы потоков лежит посимвольная передача данных, основным назначением потоков является передача объектов (экземпляров класса). С потоками могут взаимодействовать только экземпляры классов, которые соответствуют протоколу SCStreaming:


Методы протокола SCStreaming

Для взаимодействия с потоками протокол SCStreaming объявляет следующие методы:

- (void)writeToStream:(SCStream *)stream;
- (instancetype)initWithStream:(SCStream *)stream;

Кроме метода инициализации экземпляра класса может объявляться классовый метод для создания экземпляра класса на основании данных из потока. Приведем пример такого объявления в категории NSString(SCString):

+ (NSString *)stringWithStream:(SCStream *)stream;

Класс SCFileStream использует ряд других методов протокола SCStreaming, которые описываются в соответствующем разделе руководства программиста.


Методы класса SCStream

Для загрузки и записи объектов используются следующие методы класса SCStream:

- (id)readObject;
- (void)writeObject:(id<SCStreaming>)object;

С помощью метода writeObject: осуществляется запись существующего экземпляра класса в поток. Непосредственно перед записью механизм потоков идентифицирует класс, к которому относится сохраняемый экземпляр и записывает в поток служебную информацию, необходимую для последующей загрузки сохраненного экземпляра. Затем поток вызывает метод writeToStream: экземпляра класса, который и записывает в поток собственные данные экземпляра.

Метод readObject на основании служебной информации в потоке определяет, к какому классу относится загружаемый объект, создает экземпляр соответствующего класса и передает управление методу initWithStream:, который и осуществляет загрузку данных именно необходимого класса.

Приведем пример использования методов writeObject: и readObject:

SCFileStream *outputStream = [SCFileStream writeOnlyFileStreamWithPath:@"/tmp/information.dat"];
[outputStream writeObject:@"Sample String"];
[outputStream writeObject:@"This is a test"];
[outputStream writeObject:[NSNull null]];
[outputStream writeObject:[NSNumber numberWithInteger:19091975]];
[outputStream close];
SCFileStream *inputStream = [SCFileStream readOnlyFileStreamWithPath:@"/tmp/information.dat"];
SCInteger counter = 0;
while ( YES) {
id object = [inputStream readObject];
if ( !object) break;
NSLog( @"Object %d: %@", counter, object);
counter++;
}
[inputStream close];
2016-07-06 15:37:15.691 libtest[8743:2490662] Object 0: Sample String
2016-07-06 15:37:15.692 libtest[8743:2490662] Object 1: This is a test
2016-07-06 15:37:15.693 libtest[8743:2490662] Object 2: <null>
2016-07-06 15:37:15.694 libtest[8743:2490662] Object 3: 19091975

Потоки и текстовые файлы

В отличие от обычных файлов, текстовые файлы состоят не из последовательности символов, а из строк символов различной длины, каждая из которых заканчивается специальным символов конца строки. Для работы с такими данными механизм потоков в классе SCStream объявляет ряд методов.

Запись строк в текстовый файл осуществляется через следующие методы:

- (void)writeString:(NSString *)string encoding:(NSStringEncoding)encoding;
- (void)writeString:(NSString *)string;

Приведем пример записи текстовых строк в выходной поток:

[stdoutStream writeString:@"This is a test"];
[stdoutStream writeString:@"This is a test again"];
This is a test
This is a test again

Чтение текстовых данных из потоков осуществляется с помощью методов:

- (NSString *)readStringWithEncoding:(NSStringEncoding)encoding max:(SCInteger)max;
- (NSString *)readStringWithEncoding:(NSStringEncoding)encoding;
- (NSString *)readStringWithMax:(SCInteger)max;
- (NSString *)readString;

Приведем пример чтения строк из потока:

SCFileStream *file = [SCFileStream readOnlyFileStreamWithPath:@"/etc/afpovertcp.cfg"];
NSString *string;
while ( ( string = [file readString])) NSLog( @"%@", string);
[file close];
2016-07-06 17:46:00.777 libtest[9504:2628316] #
2016-07-06 17:46:00.777 libtest[9504:2628316] # /etc/afpovertcp.cfg is used to set the system-wide AFP defaults
2016-07-06 17:46:00.777 libtest[9504:2628316] # for the LibcAT AppleTalk library.
2016-07-06 17:46:00.778 libtest[9504:2628316] #
2016-07-06 17:46:00.778 libtest[9504:2628316] # Copyright 1998 Apple Computer, Inc.
2016-07-06 17:46:00.778 libtest[9504:2628316] #
2016-07-06 17:46:00.778 libtest[9504:2628316] # If this file exists, TCP/IP will be used as the default transport
2016-07-06 17:46:00.778 libtest[9504:2628316] # protocol for AFP. Otherwise ATP will be used.
2016-07-06 17:46:00.778 libtest[9504:2628316] #
2016-07-06 17:46:00.779 libtest[9504:2628316] # Supported commands are:
2016-07-06 17:46:00.779 libtest[9504:2628316] #
2016-07-06 17:46:00.779 libtest[9504:2628316] # quantum [quantum size]
2016-07-06 17:46:00.779 libtest[9504:2628316] # 16384 is a reasonable value; 4624 is the default.
2016-07-06 17:46:00.814 libtest[9504:2628316] #
2016-07-06 17:46:00.814 libtest[9504:2628316] # port [TCP listen port]
2016-07-06 17:46:00.814 libtest[9504:2628316] # The default is 548.
2016-07-06 17:46:00.815 libtest[9504:2628316] #
2016-07-06 17:46:00.815 libtest[9504:2628316] # It is legal for this file to exist and for it to have no contents.
2016-07-06 17:46:00.815 libtest[9504:2628316] #
2016-07-06 17:46:00.815 libtest[9504:2628316] quantum 16384

Протокол делегирования SCStreamDelegate

Если для потока задан объект делегирования, соответствующий протоколу SCStreamDelegate, при наступлении определенных событий механизм потоков будет вызывать соответствующие методы объекта делегирования.

Протокол делегирования определяет методы для реакции на следующие события:

Дочерние классы могут добавлять в объект делегирования обработчики собственных событий. Именно так делает класс SCFileStream.

Полный список методов приведен в описании соответствующих протокола и класса SCStreamDelegate.


Статистические данные

В ходе своей работы поток ведет накопление базовых статистических данных. Доступ к этим данным осуществляется через объявленные в классе SCStream статистические свойства (доступны только для чтения):

@property (nonatomic, assign, readonly, getter=totalRead) SCULong totalRead;
@property (nonatomic, assign, readonly, getter=totalWrite) SCULong totalWrite;
@property (nonatomic, assign, readonly, getter=lastRead) SCULong lastRead;
@property (nonatomic, assign, readonly, getter=lastWrite) SCULong lastWrite;

Для сброса статистических данных применяется метод resetStats.


Файлы и класс SCFileStream

Как уже говорилось, класс SCStream является абстрактным классом и не может быть использован напрямую. Поэтому были созданы различные дочерние классы, центральным из которых является класс файловых потоков SCFileStream, то есть класс, который реализует один из наиболее популярных видов потоков - дисковых файлов. Данный раздел руководства рассматривает различные аспекты работы класса SCFileStream:


Методы протокола SCStreaming

Протокол SCStreaming для взаимодействия с файловыми потоками объявляет следующие методы:

- (void)writeToFileStream:(NSString *)path;
- (void)appendToFileStream:(NSString *)path;
- (instancetype)initWithFileStream:(NSString *)path;

Кроме метода инициализации экземпляра класса может объявляться классовый метод для создания экземпляра класса на основании данных из файлового потока. Приведем пример такого объявления в категории NSString(SCString):

+ (NSString *)stringWithFileStream:(NSString *)path;

Ниже мы приводим пример работы методов протокола SCStreaming с файловыми потоками:

NSString *source = @"This is a test again";
[source writeToFileStream:@"/tmp/string.dat"];
NSString *string = [NSString stringWithFileStream:@"/tmp/string.dat"];
NSLog( @"%@", string);
2016-07-06 16:34:03.204 libtest[9064:2557807] This is a test again

Обработка ошибок файлового потока

Ошибки файловых потоков обрабатываются точно также, как и ошибки класса SCStream, только для данных ошибок в классе SCStreamException определены следующие исключительные ситуации:


Определение состояния файлового потока

В дополнение к кодам состояний класса SCStream класс файловых потоков SCFileStream через дополнительный тип SCFileStreamStatus следующие коды состояния:


Режимы открытия файловых потоков

Файловый поток может быть открыт в различных режимах. Режим открытия определяется свойством (только для чтения) класса SCFileStream:

@property (nonatomic, readonly, assign) SCFileStreamOpenMode openMode;

Тип SCFileStreamOpenMode определяет следующие режимы открытия файловых потоков:

Режим открытия определяется при вызове методов открытия, инициализации и создания потоков и не меняется во время операций чтения, записи и позиционирования. Изменение режима открытия без предварительного закрытия и последующего нового открытия потока невозможно.


Открытие и закрытие файловых потоков

Класс SCFileStream объявляет следующие методы открытия файловых потоков:

- (void)openWithPath:(NSString *)path mode:(SCFileStreamOpenMode)mode handling:(SCStreamErrorHandling)handling;
- (void)openWithPath:(NSString *)path mode:(SCFileStreamOpenMode)mode;
- (void)openWithPath:(NSString *)path;
- (void)openReadOnlyWithPath:(NSString *)path;
- (void)openWriteOnlyWithPath:(NSString *)path;
- (void)openAppendWithPath:(NSString *)path;

При успешном открытии состояние потока устанавливается равным SCFileStreamOK, а свойство opened возвращает значение YES. Если какой-либо метод вызывается для уже открытого потока (opened == YES), то вызов метода игнорируется - поток остается в предыдущем режиме и состоянии.

Для закрытия потока в классе SCFileStream объявлен следующий метод:

- (void)close;

Метод закрывает ранее открытый файловый поток и сбрасывает значение свойства opened в значение NO. Попытка вызова метода для закрытого потока игнорируется.


Создание файловых потоков

Класс SCFileStream объявляет следующие методы для создания файловых потоков:

+ (instancetype)fileStreamWithPath:(NSString *)path
delegate:(id<SCStreamDelegate>)delegate
handling:(SCStreamErrorHandling)handling;
+ (instancetype)fileStreamWithPath:(NSString *)path mode:(SCFileStreamOpenMode)mode delegate:(id<SCStreamDelegate>) delegate;
+ (instancetype)fileStreamWithPath:(NSString *)path mode:(SCFileStreamOpenMode)mode;
+ (instancetype)fileStreamWithPath:(NSString *)path;
+ (instancetype)readOnlyFileStreamWithPath:(NSString *)path;
+ (instancetype)writeOnlyFileStreamWithPath:(NSString *)path;
+ (instancetype)appendFileStreamWithPath:(NSString *)path;
+ (instancetype)fileStream;

Все методы, кроме fileStream, осуществляют открытие созданного файлового потока. Если данная операция прошла успешно, то свойству opened присваивается значение YES, а свойство status принимает значение SCFileStreamOK.

Приводим пример использования методов создания файловых потоков:

NSLog( @"/etc/ttys status: %d", ttys.status);
if ( ttys.opened) NSLog( @"/etc/ttys is opened");
[ttys close];
2016-07-07 03:20:14.014 libtest[11678:3116658] /etc/ttys status: 0
2016-07-07 03:20:14.014 libtest[11678:3116658] /etc/ttys is opened

Инициализация файловых потоков

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

- (instancetype)initWithPath:(NSString *)path
delegate:(id<SCStreamDelegate>)delegate
handling:(SCStreamErrorHandling)handling;
- (instancetype)initWithPath:(NSString *)path mode:(SCFileStreamOpenMode)mode delegate:(id<SCStreamDelegate>)delegate;
- (instancetype)initWithPath:(NSString *)path mode:(SCFileStreamOpenMode)mode;
- (instancetype)initWithPath:(NSString *)path;
- (instancetype)initReadOnlyWithPath:(NSString *)path;
- (instancetype)initWriteOnlyWithPath:(NSString *)path;
- (instancetype)initAppendWithPath:(NSString *)path;
- (instancetype)init;

Все методы, кроме init, осуществляют открытие инициализированного файлового потока. Если данная операция прошла успешно, то свойству opened присваивается значение YES, а свойство status принимает значение SCFileStreamOK.


Позиционирование в файловых потоках

Реализующие доступ к обычным файлам потоки на основе класса SCFileStream поддерживают позиционирование, то есть изменение положения указателя следующей операции чтения или записи.

Класс SCFileStream содержит следующие методы позиционирования в файловых потоках:

@property (nonatomic, readonly, assign) BOOL eof;
- (void)setOffset:(NSInteger)offset whence:(SCFileStreamOffsetWhence)whence;
- (void)setOffset:(NSInteger)offset;
- (NSInteger)offset;
- (void)rewind;

При использовании для позиционирования метода setOffset:whence: в качестве второго аргумента передается направление позиционирования, которое определяется типом SCFileStreamOffsetWhence, содержащим следующие константы:


Методы протокола делегирования SCStreamDelegate

Класс SCFileStream дополняет протокол делегирования SCStreamDelegate методами, которые реагируют на такие события, как открытие и закрытие файловых потоков.


Стандартные потоки ввода-вывода

В состав библиотеки входят три дочерних класса потоков для предоставления программистам доступа к стандартным потокам ввода и вывода:

Все три вышеуказанных класса являются потомками класса SCStream. В последующих разделах каждый из классов описывается более подробно.


Стандартный поток ввода SCStandardInputStream

Класс SCStandardInputStream предоставляет программистам доступ к стандартному потоку ввода stdin. Данный поток обеспечивает только операции чтения.

Для обеспечения доступа к данному потоку в классе объявлены следующие методы:

+ (instancetype)stdinStreamWithDelegate:(id<SCStreamDelegate>)delegate;
+ (instancetype)stdinStream;

Обращаем внимание, что оба вышеупомянутых метода всегда возвращают указатель на один и тот же поток - это связано с тем, что стандартный поток ввода stdin в операционной системе существует в единственном экземпляре. К тому же существование нескольких экземпляров класса потенциально может привести к коллизиям, особенно если эти несколько объектов были созданы в различных нитях процесса.

Ниже приводится пример использования стандартного потока ввода:

while ( !input.eof) {
NSString *string = [input readString];
if ( string) NSLog( @"%@", string);
}
Sample input string
2016-07-08 00:54:46.809 libtest[17772:4042392] Sample input string
Request for proposal
2016-07-08 00:54:54.691 libtest[17772:4042392] Request for proposal
Last entered string
2016-07-08 00:55:01.249 libtest[17772:4042392] Last entered string

Стандартный поток вывода SCStandardOutputStream

Класс SCStandardOutputStream предоставляет программистам доступ к стандартному потоку вывода stdout. Данный поток обеспечивает только операции записи.

Для обеспечения доступа к данному потоку в классе объявлены следующие методы:

+ (instancetype)stdoutStreamWithDelegate:(id<SCStreamDelegate>)delegate;
+ (instancetype)stdoutStream;

Обращаем внимание, что оба вышеупомянутых метода всегда возвращают указатель на один и тот же поток - это связано с тем, что стандартный поток вывода stdout в операционной системе существует в единственном экземпляре. К тому же существование нескольких экземпляров класса потенциально может привести к коллизиям, особенно если эти несколько объектов были созданы в различных нитях процесса.

Ниже приводится пример использования стандартного потока вывода:

[output writeString:@"Sample output string"];
[output writeString:@"This is a test string"];
[output writeString:@"Last output string"];
Sample output string
This is a test string
Last output string

Поток стандартной ошибки SCStandardErrorStream

Класс SCStandardErrorStream предоставляет программистам доступ к стандартному потоку ошибок stderr. Данный поток обеспечивает только операции записи.

Для обеспечения доступа к данному потоку в классе объявлены следующие методы:

+ (instancetype)stderrStreamWithDelegate:(id<SCStreamDelegate>)delegate;
+ (instancetype)stderrStream;

Обращаем внимание, что оба вышеупомянутых метода всегда возвращают указатель на один и тот же поток - это связано с тем, что стандартный поток ошибок stderr в операционной системе существует в единственном экземпляре. К тому же существование нескольких экземпляров класса потенциально может привести к коллизиям, особенно если эти несколько объектов были созданы в различных нитях процесса.

Ниже приводится пример использования стандартного потока ошибок:

[error writeString:@"System error: 2319"];
[error writeString:@"Application error: 2315"];
[error writeString:@"Fatal falture"];
System error: 2319
Application error: 2315
Fatal falture

Нулевой поток SCNullStream

Класс SCNullStream является потомком класса SCStream и предоставляет доступ к системному устройству /dev/null. Данный поток обеспечивает только операции записи. Основное назначение нулевого потока - возможность записи в него неограниченного количества данных (все передаваемые в поток данные уничтожаются).

Для обеспечения доступа к данному потоку в классе объявлены следующие методы:

+ (instancetype)nullStreamWithDelegate:(id<SCStreamDelegate>)delegate;
+ (instancetype)nullStream;

Обращаем внимание, что оба вышеупомянутых метода всегда возвращают указатель на один и тот же поток - это связано с тем, что нулевой поток /dev/null в операционной системе существует в единственном экземпляре. К тому же существование нескольких экземпляров класса потенциально может привести к коллизиям, особенно если эти несколько объектов были созданы в различных нитях процесса.


Коллекции

Коллекции представляют собой экземпляры классов, которые являются контейнерами для экземпляров других классов. Типичным примером коллекций являются массивы экземпляров класса. В состав библиотеки входят два вида коллекций:

Коллекции библиотеки взаимодействуют с обрабатываемыми экземплярами классов через методы протокола SCCollectioning.

Содержимое раздела:


Иерархия классов коллекций

collections.png

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


Виды классов коллекций

В целях упорядочения распределения различного функционала классов коллекций, а также для более простого добавления в стандартные классы совместимого с нашим функционала, нами был разработан ряд протоколов, соответствие которым и определяет совместимость с нашим механизмом коллекций. К таким протоколам относятся:

В следующих параграфах данные протоколы будут рассмотрены более подробно.


Протокол SCCollection

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

Протокол объявляет следующие обязательные для реализации свойства:

@property (nonatomic, readonly, retain) NSString *name;
@property (nonatomic, readonly, assign) SCIndex count;
@property (nonatomic, readonly, assign) BOOL empty;
@property (nonatomic, readonly, assign) BOOL readOnly;
@property (nonatomic, readonly, retain) id<SCCollectionDelegate> delegate;

Классы и категории коллекций должны поддерживать следующие методы инициализации:

- (instancetype)initWithCollection:(id<SCCollection>)collection;

Протокол требует реализации следующих методов поиска данных:

- (BOOL)containsObject:(id<SCCollectioning>)object;
- (BOOL)containsObjects:(id<SCCollectioning>)object, ...;
- (BOOL)containsCollection:(id<SCCollection>)collection;
- (BOOL)containsAnyObject:(id<SCCollectioning>)object, ...;
- (BOOL)containsAnyObjectFromCollection:(id<SCCollection>)collection;

Для обеспечения свободного преобразования одних типов коллекций в другие протокол <SCCollection> обязует программистов реализовать следующие свойства:

@property (nonatomic, readonly, assign) SCArray *array;
@property (nonatomic, readonly, assign) SCSet *set;
@property (nonatomic, readonly, assign) SCOrderedSet *orderedSet;
@property (nonatomic, readonly, assign) SCDictionary *dictionary;
@property (nonatomic, readonly, assign) SCStack *stack;
@property (nonatomic, readonly, assign) SCQueue *queue;
@property (nonatomic, readonly, assign) SCUnidirectionalList *unidirectionalList;
@property (nonatomic, readonly, assign) SCBidirectionalList *bidirectionalList;
@property (nonatomic, readonly, retain) NSArray *foundationArray;
@property (nonatomic, readonly, retain) NSSet *foundationSet;
@property (nonatomic, readonly, retain) NSOrderedSet *foundationOrderedSet;
@property (nonatomic, readonly, retain) NSDictionary *foundationDictionary;

Внимание! При работе с экземплярами класса NSOrderedSet вместо свойства array необходимо использовать свойство libraryArray из-за наличия в классе метода с данным именем.

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

@property (nonatomic, readonly, assign) SCCollectionType collectionType;
@property (nonatomic, readonly, assign) BOOL isCollection;
@property (nonatomic, readonly, assign) BOOL isLibraryCollection;
@property (nonatomic, readonly, assign) BOOL isFoundationCollection;
@property (nonatomic, readonly, assign) BOOL isArray;
@property (nonatomic, readonly, assign) BOOL isLibraryArray;
@property (nonatomic, readonly, assign) BOOL isFoundationArray;
@property (nonatomic, readonly, assign) BOOL isSet;
@property (nonatomic, readonly, assign) BOOL isLibrarySet;
@property (nonatomic, readonly, assign) BOOL isFoundationSet;
@property (nonatomic, readonly, assign) BOOL isOrderedSet;
@property (nonatomic, readonly, assign) BOOL isLibraryOrderedSet;
@property (nonatomic, readonly, assign) BOOL isFoundationOrderedSet;
@property (nonatomic, readonly, assign) BOOL isDictionary;
@property (nonatomic, readonly, assign) BOOL isLibraryDictionary;
@property (nonatomic, readonly, assign) BOOL isFoundationDictionary;
@property (nonatomic, readonly, assign) BOOL isStack;
@property (nonatomic, readonly, assign) BOOL isQueue;
@property (nonatomic, readonly, assign) BOOL isList;
@property (nonatomic, readonly, assign) BOOL isSortable;

Также протокол объявляет необязательные свойства поддержки счетчиков объектов коллекций:

@property (nonatomic, readonly, assign) NSEnumerator *objectEnumerator;
@property (nonatomic, readonly, assign) NSEnumerator *reverseObjectEnumerator;

Поддержка классами коллекций оператора for..in обеспечивается реализацией следующего метода протокола:

- (NSUInteger)countByEnumeratingWithState:(NSFastEnumerationState *)state objects:(id *)objects count:(NSUInteger)count;

Для выполнения операций сравнения коллекций протокол объявляет следующие методы:

- (BOOL)isEqualToCollection:(id<SCCollection>)collection;

Описание вышеперечисленных свойств и методов приводится в соответствующих разделах руководства программиста.


Протокол SCMutableCollection

Протокол SCMutableCollection расширяет протокол SCCollection, декларируя методы, которые должны быть реализованы в коллекциях, которые разрешают изменение своего содержимого. Все классы коллекций библиотеки соответствуют данному протоколу. Также этому протоколу соответствуют категории, которые расширяют функциональность стандартных классов:

Протокол требует обязательной реализации следующих методов копирования коллекций:

- (void)setCollection:(id<SCCollection>)collection;
- (void)setObject:(id<SCCollectioning>)object;
- (void)setObjects:(id<SCCollectioning>)object, ...;

В соответствии с протоколом обязательно должны быть реализованы методы добавления объектов:

- (void)addObject:(id<SCCollectioning>)object;
- (void)addObjects:(id<SCCollectioning>)object, ...;
- (void)addCollection:(id<SCCollection>)collection;

Также протокол требует реализации следующих методов удаления объектов из коллекций:

- (void)removeAllObjects;
- (void)removeObjectsWithClass:(Class)oclass;
- (void)removeObjectsWithClassName:(NSString *)name;
- (void)removeCollection:(id<SCCollection>)collection;
- (void)removeObject:(id<SCCollectioning>)object;
- (void)removeObjects:(id<SCCollectioning>)object, ...;

Описание вышеперечисленных методов приводится в соответствующих разделах данного руководства.


Протокол SCIndexedCollection

Протокол объявляет методы, которые должны поддерживать индексируемые коллекции, то есть коллекции, обеспечивающие доступ к объектам с помощью индексов. Методы протокола SCIndexedCollection не вносят каких-либо изменений в содержимое коллекций. Данному протоколу соответствуют следующие классы библиотеки:

Также данному протоколу соответствуют следующие категории, расширяющие функционал стандартных классов:

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

@property (nonatomic, readonly, assign) id firstObject;
@property (nonatomic, readonly, assign) id lastObject;
- (id)objectAtIndex:(SCIndex)index;
- (id)objectAtIndexedSubscript:(SCIndex)index;

Также протокол требует реализации следующих свойств и методов поиска объектов:

- (SCIndex)indexOfObject:(id<SCCollectioning>)object;
@property (nonatomic, readonly, assign) SCIndex indexOfLastObject;

Описание вышеуказанных методов находится в соответствующих разделах данного руководства.


Протокол SCMutableIndexedCollection

Протокол SCMutableIndexedCollection объявляет методы, которые могут вносить изменения в индексируемые коллекции. К таким коллекциям относятся следующие классы:

Также данному протоколу соответствуют следующие категории, расширяющие функционал стандартных классов:

Протокол объявляет следующие обязательные методы:

- (void)insertObject:(id<SCCollectioning>)object atIndex:(SCIndex)index;
- (void)removeObjectAtIndex:(SCIndex)index;
- (void)removeObjectsAtIndexes:(NSIndexSet *)indexes;
- (void)replaceObjectAtIndex:(SCIndex)index withObject:(id<SCCollectioning>)object;
- (void)setObject:(id<SCCollectioning>)object atIndexedSubscript:(SCIndex)index;

Описание данных методов приводится в соответствующих разделах руководства программиста.


Протокол SCKeyedCollection

Протокол объявляет методы, которые должны поддерживать коллекции с поддержкой ключей, то есть коллекции, обеспечивающие доступ к объектам с помощью ключей. Методы протокола SCKeyedCollection не вносят каких-либо изменений в содержимое коллекций. Данному протоколу соответствуют следующие классы библиотеки:

Также данному протоколу соответствуют следующие категории, расширяющие функционал стандартных классов:

Протокол декларирует следующие обязательные свойства и методы для доступа к объектам коллекций:

- (id)objectForKey:(NSString *)key;
- (id)objectForKeyedSubscript:(NSString *)key;
- (id)valueForKey:(NSString *)key;

Описание вышеуказанных методов находится в соответствующих разделах данного руководства.


Протокол SCMutableKeyedCollection

Протокол SCMutableKeyedCollection объявляет методы, которые могут вносить изменения в коллекции с поддержкой ключей. К таким коллекциям относятся следующие классы:

Также данному протоколу соответствуют следующие категории, расширяющие функционал стандартных классов:

Протокол объявляет следующие обязательные методы:

- (void)setObject:(id<SCCollectioning>)object forKey:(NSString *)key;
- (void)setObject:(id<SCCollectioning>)object forKeyedSubscript:(NSString *)key;
- (void)setValue:(id<SCCollectioning>)value forKey:(NSString *)key;
- (void)removeObjectForKey:(NSString *)key;

Описание данных методов приводится в соответствующих разделах руководства программиста.


Типы поддержки коллекций

Для поддержки коллекций в заголовочном файле SCCollectionProtocols.h объявлены следующие типы:

SCIndex - Тип индекса элементов коллекций и строк текстовых объектов
SCCollectionType - Тип перечисления видов коллекций

Свойства коллекций

Класс SCCollection и все его потомки объявляют следующие свойства:

@property (nonatomic, readwrite, retain) NSString *name;
@property (nonatomic, readonly, assign) SCIndex count;
@property (nonatomic, readonly, assign) BOOL empty;
@property (nonatomic, readwrite, assign) BOOL readOnly;
@property (nonatomic, readwrite, retain) id<SCCollectionDelegate> delegate;
@property (nonatomic, readonly, copy) NSString *typeName;

Копирование коллекций

Методы копирования удаляют текущее содержимое существующей коллекции и вместо него помещает содержимое переданной коллекции или другого объекта. Класс SCCollection объявляет следующие методы копирования:

- (void)setCollection:(id<SCCollection>)collection;
- (void)setObject:(id<SCCollectioning>)object;
- (void)setObjects:(id<SCCollectioning>)object, ...;

Если коллекция находится в режиме только для чтения (свойство readOnly установлено в значение YES), коллекция генерирует ошибку SCL-20043.


Сравнение коллекций

Класс SCCollection объявляет ряд методов, которые выполняют сравнение коллекции с другими коллекциями:

- (BOOL)isEqualToCollection:(id<SCCollection>)collection;
- (BOOL)isEqual:(id)object;

Перечисление коллекций

В состав класса SCCollection входят свойства и методы, обеспечивающие перечисление объектов коллекции:

@property (nonatomic, readonly, assign) NSEnumerator *objectEnumerator;
@property (nonatomic, readonly, assign) NSEnumerator *reverseObjectEnumerator;
- (void)enumerateWithDelegate:(id<SCCollectionDelegate>)delegate;
- (void)enumerate;
- (void)reverseEnumerateWithDelegate:(id<SCCollectionDelegate>)delegate;
- (void)reverseEnumerate;

Также класс SCCollection и его дочерние классы с версии 1.2.5 поддерживают оператор for..in, введенный в Objective C начиная с версии 2.0:

SCArray *array = [SCArray arrayWithObjects:@100, @"200", @"300", @400, nil];
for ( id object in array) NSLog( @"%@", object);
2017-09-10 19:42:23.832149+0300 libtest[3335:100619] 100
2017-09-10 19:42:23.832178+0300 libtest[3335:100619] 200
2017-09-10 19:42:23.832203+0300 libtest[3335:100619] 300
2017-09-10 19:42:23.832249+0300 libtest[3335:100619] 400

Преобразование коллекций

Класс SCCollection декларирует ряд свойств, которые отвечают за преобразование экземпляров одного класса коллекций в экземпляр другого класса коллекций:

@property (nonatomic, readonly, assign) SCArray *array;
@property (nonatomic, readonly, assign) SCSet *set;
@property (nonatomic, readonly, assign) SCOrderedSet *orderedSet;
@property (nonatomic, readonly, assign) SCDictionary *dictionary;
@property (nonatomic, readonly, assign) SCStack *stack;
@property (nonatomic, readonly, assign) SCQueue *queue;
@property (nonatomic, readonly, assign) SCUnidirectionalList *unidirectionalList;
@property (nonatomic, readonly, assign) SCBidirectionalList *bidirectionalList;
@property (nonatomic, readonly, assign) NSArray *foundationArray;
@property (nonatomic, readonly, assign) NSSet *foundationSet;
@property (nonatomic, readonly, assign) NSOrderedSet *foundationOrderedSet;
@property (nonatomic, readonly, assign) NSDictionary *foundationDictionary;

Добавление объектов

Класс SCCollection объявляет следующие основные методы добавления объектов в состав коллекции:

- (void)addObject:(id<SCCollectioning>)object;
- (void)addObjects:(id<SCCollectioning>)object, ...;
- (void)addCollection:(id<SCCollection>)collection;

Если вышеперечисленные методы вызываются для находящейся в режиме только для чтения коллекции, то механизм коллекций генерирует исключительную ситуацию SCL-20043.


Удаление объектов

Класс SCCollection объявляет следующие методы удаления объектов из коллекции:

- (void)removeAllObjects;
- (void)removeObjectsWithClass:(Class)oclass;
- (void)removeObjectsWithClassName:(NSString *)name;
- (void)removeCollection:(id<SCCollection>)collection;
- (void)removeObject:(id<SCCollectioning>)object;
- (void)removeObjects:(id<SCCollectioning>)object, ...;

Если методы удаления вызываются для коллекции, которая находится в режиме только для чтения, то генерируется исключительная ситуация SCL-20043.


Поиск элементов коллекции

Методы поиска определяют наличие в коллекции указанных в качестве аргумента объектов. Класс SCCollection объявляет следующие методы поиска объектов:

- (BOOL)containsObject:(id<SCCollectioning>)object;
- (BOOL)containsObjects:(id<SCCollectioning>)object, ...;
- (BOOL)containsCollection:(id<SCCollection>)collection;
- (BOOL)containsAnyObject:(id<SCCollectioning>)object, ...;
- (BOOL)containsAnyObjectFromCollection:(id<SCCollection>)collection;

Определение типов коллекций

Класс SCCollection объявляет свойства, позволяющие программистам определить, к какому типу коллекции относится конкретный экземпляр класса:

@property (nonatomic, readonly, assign) SCCollectionType collectionType;
@property (nonatomic, readonly, assign) BOOL isCollection;
@property (nonatomic, readonly, assign) BOOL isLibraryCollection;
@property (nonatomic, readonly, assign) BOOL isFoundationCollection;
@property (nonatomic, readonly, assign) BOOL isArray;
@property (nonatomic, readonly, assign) BOOL isLibraryArray;
@property (nonatomic, readonly, assign) BOOL isFoundationArray;
@property (nonatomic, readonly, assign) BOOL isSet;
@property (nonatomic, readonly, assign) BOOL isLibrarySet;
@property (nonatomic, readonly, assign) BOOL isFoundationSet;
@property (nonatomic, readonly, assign) BOOL isOrderedSet;
@property (nonatomic, readonly, assign) BOOL isLibraryOrderedSet;
@property (nonatomic, readonly, assign) BOOL isFoundationOrderedSet;
@property (nonatomic, readonly, assign) BOOL isDictionary;
@property (nonatomic, readonly, assign) BOOL isLibraryDictionary;
@property (nonatomic, readonly, assign) BOOL isFoundationDictionary;
@property (nonatomic, readonly, assign) BOOL isStack;
@property (nonatomic, readonly, assign) BOOL isQueue;
@property (nonatomic, readonly, assign) BOOL isList;
@property (nonatomic, readonly, assign) BOOL isSortable;

Кроме методов экземпляров класса SCCollection объявляет классовые методы, позволяющие определить тип коллекции переданного экземпляра класса:

+ (BOOL)isCollection:(id)object;
+ (BOOL)isLibraryCollection:(id)object;
+ (BOOL)isFoundationCollection:(id)object;
+ (BOOL)isArray:(id)object;
+ (BOOL)isLibraryArray:(id)object;
+ (BOOL)isFoundationArray:(id)object;
+ (BOOL)isSet:(id)object;
+ (BOOL)isLibrarySet:(id)object;
+ (BOOL)isFoundationSet:(id)object;
+ (BOOL)isOrderedSet:(id)object;
+ (BOOL)isLibraryOrderedSet:(id)object;
+ (BOOL)isFoundationOrderedSet:(id)object;
+ (BOOL)isDictionary:(id)object;
+ (BOOL)isLibraryDictionary:(id)object;
+ (BOOL)isFoundationDictionary:(id)object;
+ (BOOL)isStack:(id)object;
+ (BOOL)isQueue:(id)object;
+ (BOOL)isList:(id)object;
+ (BOOL)isSortable:(id)object;

Также класс SCCollection объявляет ряд классовых методов, которые определяют принадлежность к тому или иному типу коллекции класса с указанным именем:

+ (BOOL)isCollectionClass:(NSString *)name;
+ (BOOL)isLibraryCollectionClass:(NSString *)name;
+ (BOOL)isFoundationCollectionClass:(NSString *)name;
+ (BOOL)isArrayClass:(NSString *)name;
+ (BOOL)isLibraryArrayClass:(NSString *)name;
+ (BOOL)isFoundationArrayClass:(NSString *)name;
+ (BOOL)isSetClass:(NSString *)name;
+ (BOOL)isLibrarySetClass:(NSString *)name;
+ (BOOL)isFoundationSetClass:(NSString *)name;
+ (BOOL)isOrderedSetClass:(NSString *)name;
+ (BOOL)isLibraryOrderedSetClass:(NSString *)name;
+ (BOOL)isFoundationOrderedSetClass:(NSString *)name;
+ (BOOL)isDictionaryClass:(NSString *)name;
+ (BOOL)isLibraryDictionaryClass:(NSString *)name;
+ (BOOL)isFoundationDictionaryClass:(NSString *)name;
+ (BOOL)isStackClass:(NSString *)name;
+ (BOOL)isQueueClass:(NSString *)name;
+ (BOOL)isListClass:(NSString *)name;
+ (BOOL)isSortableClass:(NSString *)name;

Массивы

Массивы - разновидность коллекций, которая обеспечивает доступ к отдельным объектам массива с помощью индексации, то есть с указанием номера (индекса) нужного объекта. Благодаря этому массивы являются коллекциями с произвольным доступом. Массивы также являются сортируемыми коллекциями.

В библиотеке функции массивов реализует класс SCArray. Экземпляры класса могут поддерживать как доступ к данным массива, так и внесение изменений в массивы.


Создание массивов

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

+ (instancetype)arrayWithCoder:(NSCoder *)coder;
+ (instancetype)arrayWithContentsOfSerializedFile:(NSString *)path;
+ (instancetype)arrayWithDataDictionary:(NSDictionary *)dictionary;
+ (instancetype)arrayWithDataDictionaryFromFile:(NSString *)path;
+ (instancetype)arrayWithStream:(SCStream *)stream;
+ (instancetype)arrayWithFileStream:(NSString *)path;
+ (instancetype)arrayWithData:(NSData *)data;
+ (instancetype)arrayWithContentsOfFile:(NSString *)path;
+ (instancetype)arrayWithContentsOfURL:(NSURL *)url;
+ (instancetype)arrayWithContentsOfURLString:(NSString *)urlString;

Создание массивов может быть выполнено с помощью следующих классовых методов:

+ (instancetype)arrayWithName:(NSString *)name;
+ (instancetype)arrayWithObject:(id<SCCollectioning>)object;
+ (instancetype)arrayWithObjects:(id<SCCollectioning>)object, ...;
+ (instancetype)arrayWithCollection:(id<SCCollection>)collection;
+ (instancetype)arrayWithArray:(SCArray *)array;
+ (instancetype)array;

Инициализация массивов

Класс SCArray объявляет следующие методы инициализации массивов:

- (instancetype)initWithName:(NSString *)name;
- (instancetype)initWithObject:(id<SCCollectioning>)object;
- (instancetype)initWithObjects:(id<SCCollectioning>)object, ...;
- (instancetype)initWithCollection:(id<SCCollection>)collection;
- (instancetype)initWithArray:(SCArray *)array;
- (instancetype)init;

Копирование массивов

Копирование массивов осуществляется следующими методами класса SCArray:

- (void)setArray:(SCArray *)array;

Сравнение массивов

Класс SCArray дополняет класс SCCollection следующими методами сравнения экземпляров класса:

- (BOOL)isEqualToArray:(SCArray *)array;
SCArray *array = [SCArray array];
[array addObject:@"Line 00"];
[array addObject:@"Line 01"];
[array addObject:@"Line 02"];
SCArray *source = [SCArray arrayWithName:@"SourceArray"];
[source addObject:@"Line 00"];
[source addObject:@"Line 01"];
[source addObject:@"Line 02"];
SCArray *sample = [SCArray array];
[sample addObject:@"Line 00"];
[sample addObject:@"Line 10"];
[sample addObject:@"Line 20"];
NSLog( @"[array isEqualToArray:source] = %d", [array isEqualToArray:source]);
NSLog( @"[array isEqualToArray:sample] = %d", [array isEqualToArray:sample]);
2016-07-25 01:36:51.081 libtest[11081:1745880] [array isEqualToArray:source] = 1
2016-07-25 01:36:51.081 libtest[11081:1745880] [array isEqualToArray:sample] = 0

Получение новых массивов

Получение новых массив на основании данных из существующих обеспечивается с помощью следующих методов класса SCArray:

- (SCArray *)arrayByAddingObject:(id<SCCollectioning>)object;
- (SCArray *)arrayByAddingObjects:(id<SCCollectioning>)object, ...;
- (SCArray *)arrayByAddingCollection:(id<SCCollection>)collection;
- (SCArray *)arrayByAddingObjectsFromArray:(SCArray *)array;
- (SCArray *)arrayByAddingArray:(SCArray *)array;
- (SCArray *)subarrayWithRange:(NSRange)range;

Сортировка массивов

Массивы, как и любые коллекции с индексируемым доступом к объектам, могут обеспечивать различные виды сортировки своего содержимого. Класс SCArray реализует ряд методов, которые позволяют выполнить такие операции сортировки. Для осуществления непосредственно процесса сортировки класс SCArray использует сортировщики - экземпляры классов, которые соответствуют протоколу SCSorter. При этом при вызове процессов сортировки массива программист может либо самостоятельно указать используемый сортировщик, либо воспользоваться сортировщиком по умолчанию. Более подробно сортировщики описываются в соответствующем разделе данного руководства.

В ходе выполнения операции сортировки определение последовательности объектов выполняется путем их сравнения между собой. Для этого у сравниваемых элементов вызывается метод compareWithObject: протокола SCCollectioning.

Класс SCArray объявляет следующие свойства и методы сортировки своего содержимого:

- (void)sortAscendingWithSorter:(id<SCSorter>)sorter;
- (void)sortDescendingWithSorter:(id<SCSorter>)sorter;
- (void)sortWithSorter:(id<SCSorter>)sorter;
- (void)sortAscending;
- (void)sortDescending;
- (void)sort;
- (SCArray *)ascendingSortedArrayWithSorter:(id<SCSorter>)sorter;
- (SCArray *)descendingSortedArrayWithSorter:(id<SCSorter>)sorter;
- (SCArray *)sortedArrayWithSorter:(id<SCSorter>)sorter;
@property (nonatomic, readonly, assign) SCArray *ascendingSortedArray;
@property (nonatomic, readonly, assign) SCArray *descendingSortedArray;
@property (nonatomic, readonly, assign) SCArray *sortedArray;
SCArray *array = [SCArray array];
[array addObject:@"String 04"];
[array addObject:@"String 01"];
[array addObject:@"String 00"];
[array addObject:@"String 02"];
[array addObject:@"String 03"];
NSLog( @"================ SOURCE ARRAY =================");
NSLog( @"%@", array);
[array sortAscending];
NSLog( @"=========== ASCENDING SORTED ARRAY ============");
NSLog( @"%@", array);
NSLog( @"=========== DESCENDING SORTED ARRAY ===========");
NSLog( @"%@", array);
2016-07-22 10:25:14.707 libtest[7423:1366810] ================ SOURCE ARRAY =================
2016-07-22 10:25:14.707 libtest[7423:1366810] Array count=5: (
"String 04",
"String 01",
"String 00",
"String 02",
"String 03"
)
2016-07-22 10:25:14.708 libtest[7423:1366810] =========== ASCENDING SORTED ARRAY ============
2016-07-22 10:25:14.708 libtest[7423:1366810] Array count=5: (
"String 00",
"String 01",
"String 02",
"String 03",
"String 04"
)
2016-07-22 10:25:14.708 libtest[7423:1366810] =========== DESCENDING SORTED ARRAY ===========
2016-07-22 10:25:14.708 libtest[7423:1366810] Array count=5: (
"String 04",
"String 03",
"String 02",
"String 01",
"String 00"
)

Кроме вышеперечисленных методов класс SCArray объявляет классовые методы создания массивов на основе отсортированных объектов существующих коллекций любого поддерживаемого типа:

+ (instancetype)arrayWithAscendingSortedCollection:(id<SCCollection>)collection sorter:(id<SCSorter>)sorter;
+ (instancetype)arrayWithDescendingSortedCollection:(id<SCCollection>)collection sorter:(id<SCSorter>)sorter;
+ (instancetype)arrayWithSortedCollection:(id<SCCollection>)collection sorter:(id<SCSorter>)sorter;
+ (instancetype)arrayWithAscendingSortedCollection:(id<SCCollection>)collection;
+ (instancetype)arrayWithDescendingSortedCollection:(id<SCCollection>)collection;
+ (instancetype)arrayWithSortedCollection:(id<SCCollection>)collection;

Также SCArray объявляет методы инициализации экземпляров класса на основании существующих коллекций любого типа с сортировкой содержащихся в них объектов:

- (instancetype)initWithAscendingSortedCollection:(id<SCCollection>)collection sorter:(id<SCSorter>)sorter;
- (instancetype)initWithDescendingSortedCollection:(id<SCCollection>)collection sorter:(id<SCSorter>)sorter;
- (instancetype)initWithSortedCollection:(id<SCCollection>)collection sorter:(id<SCSorter>)sorter;
- (instancetype)initWithAscendingSortedCollection:(id<SCCollection>)collection;
- (instancetype)initWithDescendingSortedCollection:(id<SCCollection>)collection;
- (instancetype)initWithSortedCollection:(id<SCCollection>)collection;

В дополнение к методам копирования коллекций, унаследованных от класса SCCollection, и методам копирования массивов, SCArray содержит методы копирования коллекций с сортировкой исходных данных:

- (void)setAscendingSortedCollection:(id<SCCollection>)collection sorter:(id<SCSorter>)sorter;
- (void)setDescendingSortedCollection:(id<SCCollection>)collection sorter:(id<SCSorter>)sorter;
- (void)setSortedCollection:(id<SCCollection>)collection sorter:(id<SCSorter>)sorter;
- (void)setAscendingSortedCollection:(id<SCCollection>)collection;
- (void)setDescendingSortedCollection:(id<SCCollection>)collection;
- (void)setSortedCollection:(id<SCCollection>)collection;

Добавление объектов в массив

В дополнение к общим для всех коллекций методам добавления объектов класс SCArray декларирует свои собственные методы, связанные прежде всего с поддержкой индексного доступа к своим объектам:

- (void)insertObject:(id<SCCollectioning>)object atIndex:(SCIndex)index;
- (void)insertAtIndex:(SCIndex)index objects:(id<SCCollectioning>)object, ...;
- (void)insertCollection:(id<SCCollection>)collection atIndex:(SCIndex)index;
- (void)insertAtIndexes:(NSIndexSet *)indexes objects:(id<SCCollectioning>)object, ...;
- (void)insertCollection:(id<SCCollection>)collection atIndexes:(NSIndexSet *)indexes;
- (void)setObject:(id<SCCollectioning>)object atIndex:(SCIndex)index;
- (void)addObjectsFromArray:(SCArray *)array;
- (void)addArray:(SCArray *)array;

Удаление объектов массива

Для реализации механизма индексного доступа к объектам класс SCArray дополняет унаследованные от класса SCCollection методы удаления объектов своими собственными методами удаления данных:

- (void)removeFirstObject;
- (void)removeLastObject;
- (void)removeObjectAtIndex:(SCIndex)index;
- (void)removeObjectsAtIndexes:(NSIndexSet *)indexes;
- (void)removeObjectsInRange:(NSRange)range;

Замена объектов массива

Класс SCArray декларирует следующие методы для осуществления замены объектов:

- (void)replaceObjectAtIndex:(SCIndex)index withObject:(id<SCCollectioning>)object;
- (void)replaceObjectsAtIndexes:(NSIndexSet *)indexes withObjects:(id<SCCollectioning>)object, ...;
- (void)replaceObjectsAtIndexes:(NSIndexSet *)indexes withCollection:(id<SCCollection>)collection;
- (void)replaceObjectsInRange:(NSRange)range withObjects:(id<SCCollectioning>)object, ...;
- (void)replaceObjectsInRange:(NSRange)range withCollection:(id<SCCollection>)collection;
- (void)setObject:(id<SCCollectioning>)object atIndexedSubscript:(SCIndex)index;

Копирование и перемещение объектов

Для копирования и перемещения объектов в массиве класс SCArray объявляет ряд методов. Рассмотрение таких методов мы начнем с метода exchangeObjectAtIndex:withObjectAtIndex:, который осуществляет обмен между объектами с указанными индексами:

- (void)exchangeObjectAtIndex:(SCIndex)index withObjectAtIndex:(SCIndex)destination;
SCArray *array = [SCArray array];
[array addObject:@"Object 00"];
[array addObject:@"Object 01"];
[array addObject:@"Object 02"];
[array addObject:@"Object 03"];
NSLog( @"%@", array);
NSLog( @"%@", array);
2016-07-22 15:38:02.392 libtest[9467:1548785] Array count=4: (
"Object 00",
"Object 01",
"Object 02",
"Object 03"
)
2016-07-22 15:38:02.392 libtest[9467:1548785] Array count=4: (
"Object 03",
"Object 01",
"Object 02",
"Object 00"
)

Для дублирования объектов в классе SCArray декларированы следующие методы:

- (void)duplicateObjectAtIndex:(SCIndex)index;
- (void)duplicateObjectsInRange:(NSRange)range;
- (void)duplicateAllObjects;
- (void)duplicate;

Чтобы данные методы могли работать, элементы массива должны соответствовать спецификации протокола SCCollectioning, и прежде всего иметь соответствующую реализацию метода copyObject.

Копирование элементов объектов (требуется реализация метода copyObject) выполняется следующими методами класса SCArray:

- (void)copyObjectAtIndex:(SCIndex)index toIndex:(SCIndex)destination;
- (void)copyObjectsInRange:(NSRange)range toIndex:(SCIndex)destination;

Перемещение объектов массива осуществляют следующие методы класса SCArray:

- (void)moveObjectAtIndex:(SCIndex)index toIndex:(SCIndex)destination;
- (void)moveObjectsInRange:(NSRange)range toIndex:(SCIndex)destination;

Дополнительно класс SCArray объявляет методы, осуществляющие реверсирование (то есть изменение порядка следования объектов массива на противоположный) содержимого массива:

- (void)reverse;
- (SCArray *)reversedArray;
SCArray *array = [SCArray array];
[array addObject:@"Object 00"];
[array addObject:@"Object 01"];
[array addObject:@"Object 02"];
[array addObject:@"Object 03"];
NSLog( @"%@", array);
[array reverse];
NSLog( @"%@", array);
2016-07-22 17:22:13.296 libtest[10119:1622519] Array count=4: (
"Object 00",
"Object 01",
"Object 02",
"Object 03"
)
2016-07-22 17:22:13.296 libtest[10119:1622519] Array count=4: (
"Object 03",
"Object 02",
"Object 01",
"Object 00"
)

Доступ к объектам массива

Класс SCArray объявляет следующие свойства и методы для доступа к объектам массива:

@property (nonatomic, readonly, assign) id firstObject;
@property (nonatomic, readonly, assign) id lastObject;
- (id)objectAtIndex:(SCIndex)index;
- (SCArray *)objectsAtIndexes:(NSIndexSet *)indexes;
- (SCArray *)objectsInRange:(NSRange)range;
- (id)objectAtIndexedSubscript:(SCIndex)index;

Поиск объектов массива

Поиск объектов массива обеспечивается объявленными в классе SCArray методами и свойствами:

- (SCIndex)indexOfObject:(id<SCCollectioning>)object;
- (SCIndex)indexOfObject:(id<SCCollectioning>)object inRange:(NSRange)range;
@property (nonatomic, readonly, assign) SCIndex indexOfLastObject;

Неупорядоченные множества

Неупорядоченное множество - разновидность коллекций, которая представляет собой неупорядоченный набор объектов. Каждый объект хранится во множестве в единственном экземпляре вне зависимости от того, сколько раз он был добавлен во множество, что отличает множество от массивов и ряда других видов коллекций. Неупорядоченное множество не гарантирует определенный порядок хранения элементов и не предоставляет прямого доступа к конкретным объектам.

В библиотеке неупорядоченные множества реализованы на базе класса SCSet:


Создание неупорядоченных множеств

Для создания неупорядоченных множеств из последовательных файлов, словарей, потоков и объектов данных в классе SCSet объявлен следующий ряд классовых методов:

+ (instancetype)setWithCoder:(NSCoder *)coder;
+ (instancetype)setWithContentsOfSerializedFile:(NSString *)path;
+ (instancetype)setWithDataDictionary:(NSDictionary *)dictionary;
+ (instancetype)setWithDataDictionaryFromFile:(NSString *)path;
+ (instancetype)setWithStream:(SCStream *)stream;
+ (instancetype)setWithFileStream:(NSString *)path;
+ (instancetype)setWithData:(NSData *)data;
+ (instancetype)setWithContentsOfFile:(NSString *)path;
+ (instancetype)setWithContentsOfURL:(NSURL *)url;
+ (instancetype)setWithContentsOfURLString:(NSString *)urlString;

Класс SCSet реализует следующие классовые методы для создания экземпляров класса:

+ (instancetype)setWithName:(NSString *)name;
+ (instancetype)setWithObject:(id<SCCollectioning>)object;
+ (instancetype)setWithObjects:(id<SCCollectioning>)object, ...;
+ (instancetype)setWithCollection:(id<SCCollection>)collection;
+ (instancetype)setWithSet:(SCSet *)set;
+ (instancetype)setWithArray:(SCArray *)array;
+ (instancetype)set;

Инициализация неупорядоченных множеств

Класс SCSet объявляет следующие методы инициализации экземпляров класса:

- (instancetype)initWithName:(NSString *)name;
- (instancetype)initWithObject:(id<SCCollectioning>)object;
- (instancetype)initWithObjects:(id<SCCollectioning>)object, ...;
- (instancetype)initWithCollection:(id<SCCollection>)collection;
- (instancetype)initWithSet:(SCSet *)set;
- (instancetype)initWithArray:(SCArray *)array;
- (instancetype)init;

Копирование неупорядоченных множеств

Класс SCSet декларирует следующие методы копирования неупорядоченных множеств:

- (void)setSet:(SCSet *)set;
- (void)setArray:(SCArray *)array;

Сравнение неупорядоченных множеств

Для сравнения неупорядоченных множеств класс SCSet декларирует следующие методы:

- (BOOL)isSubsetOfSet:(id<SCCollection>)set;
- (BOOL)intersectsSet:(id<SCCollection>)set;
- (BOOL)isEqualToSet:(SCSet *)set;
- (BOOL)isEqualToArray:(SCArray *)array;

Получение новых неупорядоченных множеств

Класс SCSet реализует ряд методов для создания новых неупорядоченных множеств на основе уже существующих неупорядоченных множеств:

- (SCSet *)setByAddingObject:(id<SCCollectioning>)object;
- (SCSet *)setByAddingObjects:(id<SCCollectioning>)object, ... NS_REQUIRES_NIL_TERMINATION;
- (SCSet *)setByAddingObjectsFromArray:(SCArray *)array;
- (SCSet *)setByAddingArray:(SCArray *)array;
- (SCSet *)setByAddingObjectsFromSet:(SCSet *)set;
- (SCSet *)setByAddingSet:(SCSet *)set;
- (SCSet *)setByAddingCollection:(id<SCCollection>)collection;

Добавление объектов

Кроме унаследованных от класса SCCollection методов класс SCSet реализует собственные методы добавления объектов:

- (void)addObjectsFromArray:(SCArray *)array;
- (void)addArray:(SCArray *)array;
- (void)addObjectsFromSet:(SCSet *)set;
- (void)addSet:(SCSet *)set;

Доступ к объектам

Для доступа к объектам неупорядоченного множества класс SCSet объявляет следующие свойства и методы:

@property (nonatomic, readonly, assign) SCArray *allObjects;
@property (nonatomic, readonly, assign) id anyObject;
- (id)member:(id<SCCollectioning>)object;

Комбинирование и рекомбинирование

Неупорядоченные множества на базе класса SCSet предоставляют следующие методы для осуществления операций комбинирования и рекомбинирования:

- (void)unionSet:(id<SCCollection>)set;
- (void)minusSet:(id<SCCollection>)set;
- (void)intersectSet:(id<SCCollection>)set;

Упорядоченные множества

Упорядоченные множества на базе класса SCOrderedSet представляют собой множества объектов, отличающиеся от неупорядоченных множеств SCSet как поддержкой определенной последовательности объектов (отсюда и название), так и индексным доступом к объектам множества.

Упорядоченные множества сходны как с массивами (порядок объектов, индексный доступ), так и с неупорядоченными множествами - каждый объект присутствует в упорядоченном множестве только один раз.


Создание упорядоченных множеств

Создание упорядоченных множеств с использованием последовательных файлов, словарей, потоков и объектов данных осуществляется следующими классовыми методами класса SCOrderedSet:

+ (instancetype)orderedSetWithCoder:(NSCoder *)coder;
+ (instancetype)orderedSetWithContentsOfSerializedFile:(NSString *)path;
+ (instancetype)orderedSetWithDataDictionary:(NSDictionary *)dictionary;
+ (instancetype)orderedSetWithDataDictionaryFromFile:(NSString *)path;
+ (instancetype)orderedSetWithStream:(SCStream *)stream;
+ (instancetype)orderedSetWithFileStream:(NSString *)path;
+ (instancetype)orderedSetWithData:(NSData *)data;
+ (instancetype)orderedSetWithContentsOfFile:(NSString *)path;
+ (instancetype)orderedSetWithContentsOfURL:(NSURL *)url;
+ (instancetype)orderedSetWithContentsOfURLString:(NSString *)urlString;

Для создания упорядоченных множеств класс SCOrderedSet декларирует следующие классовые методы

+ (instancetype)orderedSetWithName:(NSString *)name;
+ (instancetype)orderedSetWithObject:(id<SCCollectioning>)object;
+ (instancetype)orderedSetWithObjects:(id<SCCollectioning>)object, ...;
+ (instancetype)orderedSetWithCollection:(id<SCCollection>)collection;
+ (instancetype)orderedSetWithArray:(SCArray *)array;
+ (instancetype)orderedSetWithSet:(SCSet *)set;
+ (instancetype)orderedSetWithOrderedSet:(SCOrderedSet *)orderedSet;
+ (instancetype)orderedSet;

Инициализация упорядоченных множеств

Класс SCOrderedSet декларирует следующие методы инициализации упорядоченных множеств:

- (instancetype)initWithName:(NSString *)name;
- (instancetype)initWithObject:(id<SCCollectioning>)object;
- (instancetype)initWithObjects:(id<SCCollectioning>)object, ...;
- (instancetype)initWithCollection:(id<SCCollection>)collection;
- (instancetype)initWithArray:(SCArray *)array;
- (instancetype)initWithSet:(SCSet *)set;
- (instancetype)initWithOrderedSet:(SCOrderedSet *)orderedSet;
- (instancetype)init;

Копирование упорядоченных множеств

Класс SCOrderedSet объявляет следующие методы копирования упорядоченных множеств:

- (void)setSet:(SCSet *)set;
- (void)setOrderedSet:(SCOrderedSet *)orderedSet;
- (void)setArray:(SCArray *)array;

Сравнение упорядоченных множеств

Класс SCOrderedSet содержит ряд методов для выполнения сравнений с различными видами коллекций:

- (BOOL)isSubsetOfOrderedSet:(id<SCCollection>)orderedSet;
- (BOOL)isSubsetOfSet:(id<SCCollection>)set;
- (BOOL)intersectsOrderedSet:(id<SCCollection>)orderedSet;
- (BOOL)intersectsSet:(id<SCCollection>)set;
- (BOOL)isEqualToOrderedSet:(SCOrderedSet *)orderedSet;
- (BOOL)isEqualToSet:(SCSet *)set;
- (BOOL)isEqualToArray:(SCArray *)array;

Получение новых упорядоченных множеств

Класс SCOrderedSet реализует ряд методов для получения новых упорядоченных множеств на основании уже существующих упорядоченных множеств:

- (SCOrderedSet *)orderedSetByAddingObject:(id<SCCollectioning>)object;
- (SCOrderedSet *)orderedSetByAddingObjects:(id<SCCollectioning>)object, ...;
- (SCOrderedSet *)orderedSetByAddingCollection:(id<SCCollection>)collection;
- (SCOrderedSet *)orderedSetByAddingObjectsFromArray:(SCArray *)array;
- (SCOrderedSet *)orderedSetByAddingArray:(SCArray *)array;
- (SCOrderedSet *)orderedSetByAddingObjectsFromSet:(SCSet *)set;
- (SCOrderedSet *)orderedSetByAddingSet:(SCSet *)set;
- (SCOrderedSet *)orderedSetByAddingObjectsFromOrderedSet:(SCOrderedSet *)orderedSet;
- (SCOrderedSet *)orderedSetByAddingOrderedSet:(SCOrderedSet *)orderedSet;

Сортировка упорядоченных множеств

Поскольку упорядоченные множества поддерживают индексную адресацию объектов, они обеспечивают различные виды сортировки своего содержимого. Класс SCOrderedSet реализует ряд методов, которые позволяют выполнять такие операции. Для осуществления непосредственно процесса сортировки класс SCOrderedSet применяет сортировщики - экземпляры соответствующих протоколу SCSorter классов. При этом при вызове процессов сортировки массива программист может либо самостоятельно указать используемый сортировщик, либо воспользоваться сортировщиком по умолчанию. Более подробно сортировщики описываются в соответствующем разделе данного руководства.

В ходе выполнения операции сортировки определение последовательности объектов осуществляется путем их сравнения между собой. Для этого у сравниваемых элементов вызывается метод compareWithObject: протокола SCCollectioning.

Класс SCOrderedSet объявляет следующие методы и свойства сортировки своего содержимого:

- (void)sortAscendingWithSorter:(id<SCSorter>)sorter;
- (void)sortDescendingWithSorter:(id<SCSorter>)sorter;
- (void)sortWithSorter:(id<SCSorter>)sorter;
- (void)sortAscending;
- (void)sortDescending;
- (void)sort;
- (SCOrderedSet *)ascendingSortedOrderedSetWithSorter:(id<SCSorter>)sorter;
- (SCOrderedSet *)descendingSortedOrderedSetWithSorter:(id<SCSorter>)sorter;
- (SCOrderedSet *)sortedOrderedSetWithSorter:(id<SCSorter>)sorter;
@property (nonatomic, readonly, assign) SCOrderedSet *ascendingSortedOrderedSet;
@property (nonatomic, readonly, assign) SCOrderedSet *descendingSortedOrderedSet;
@property (nonatomic, readonly, assign) SCOrderedSet *sortedOrderedSet;
[orderedSet addObject:@"04"];
[orderedSet addObject:@"01"];
[orderedSet addObject:@"00"];
[orderedSet addObject:@"02"];
[orderedSet addObject:@"03"];
NSLog( @"================ SOURCE ORDERED SET =================");
NSLog( @"%@", orderedSet);
[orderedSet sortAscending];
NSLog( @"=========== ASCENDING SORTED ORDERED SET ============");
NSLog( @"%@", orderedSet);
[orderedSet sortDescending];
NSLog( @"=========== DESCENDING SORTED ORDERED SET ===========");
NSLog( @"%@", orderedSet);
2016-07-26 16:53:02.377 libtest[5100:665305] ================ SOURCE ORDERED SET =================
2016-07-26 16:53:02.377 libtest[5100:665305] Ordered set count=5: {(
"04",
"01",
"00",
"02",
"03"
)}
2016-07-26 16:53:02.378 libtest[5100:665305] =========== ASCENDING SORTED ORDERED SET ============
2016-07-26 16:53:02.378 libtest[5100:665305] Ordered set count=5: {(
"00",
"01",
"02",
"03",
"04"
)}
2016-07-26 16:53:02.378 libtest[5100:665305] =========== DESCENDING SORTED ORDERED SET ===========
2016-07-26 16:53:02.378 libtest[5100:665305] Ordered set count=5: {(
"04",
"03",
"02",
"01",
"00"
)}

Кроме вышеперечисленных методов класс SCOrderedSet объявляет классовые методы создания упорядоченных множеств на основе отсортированных объектов существующих коллекций любого поддерживаемого типа:

+ (instancetype)orderedSetWithAscendingSortedCollection:(id<SCCollection>)collection sorter:(id<SCSorter>)sorter;
+ (instancetype)orderedSetWithDescendingSortedCollection:(id<SCCollection>)collection sorter:(id<SCSorter>)sorter;
+ (instancetype)orderedSetWithSortedCollection:(id<SCCollection>)collection sorter:(id<SCSorter>)sorter;
+ (instancetype)orderedSetWithAscendingSortedCollection:(id<SCCollection>)collection;
+ (instancetype)orderedSetWithDescendingSortedCollection:(id<SCCollection>)collection;
+ (instancetype)orderedSetWithSortedCollection:(id<SCCollection>)collection;

Также SCOrderedSet объявляет методы инициализации экземпляров класса на основании существующих коллекций любого типа с сортировкой содержащихся в них объектов:

- (instancetype)initWithAscendingSortedCollection:(id<SCCollection>)collection sorter:(id<SCSorter>)sorter;
- (instancetype)initWithDescendingSortedCollection:(id<SCCollection>)collection sorter:(id<SCSorter>)sorter;
- (instancetype)initWithSortedCollection:(id<SCCollection>)collection sorter:(id<SCSorter>)sorter;
- (instancetype)initWithAscendingSortedCollection:(id<SCCollection>)collection;
- (instancetype)initWithDescendingSortedCollection:(id<SCCollection>)collection;
- (instancetype)initWithSortedCollection:(id<SCCollection>)collection;

В дополнение к методам копирования коллекций, унаследованных от класса SCCollection, и методам копирования упорядоченных, SCOrderedSet содержит методы копирования упорядоченных множеств с сортировкой исходных данных:

- (void)setAscendingSortedCollection:(id<SCCollection>)collection sorter:(id<SCSorter>)sorter;
- (void)setDescendingSortedCollection:(id<SCCollection>)collection sorter:(id<SCSorter>)sorter;
- (void)setSortedCollection:(id<SCCollection>)collection sorter:(id<SCSorter>)sorter;
- (void)setAscendingSortedCollection:(id<SCCollection>)collection;
- (void)setDescendingSortedCollection:(id<SCCollection>)collection;
- (void)setSortedCollection:(id<SCCollection>)collection;

Добавление объектов в упорядоченное множество

В дополнение к общим для всех коллекций методам добавления объектов класс SCOrderedSet декларирует свои собственные методы, связанные прежде всего с поддержкой индексного доступа к своим объектам. Обращаем внимание, что каждый объект можно добавить в упорядоченное множество только один раз - повторная попытка добавить объект будет проигнорирована:

- (void)insertObject:(id<SCCollectioning>)object atIndex:(SCIndex)index;
- (void)insertAtIndex:(SCIndex)index objects:(id<SCCollectioning>)object, ...;
- (void)insertCollection:(id<SCCollection>)collection atIndex:(SCIndex)index;
- (void)insertAtIndexes:(NSIndexSet *)indexes objects:(id<SCCollectioning>)object, ...;
- (void)insertCollection:(id<SCCollection>)collection atIndexes:(NSIndexSet *)indexes;
- (void)setObject:(id<SCCollectioning>)object atIndex:(SCIndex)index;
- (void)addObjectsFromArray:(SCArray *)array;
- (void)addArray:(SCArray *)array;
- (void)addObjectsFromSet:(SCSet *)set;
- (void)addSet:(SCSet *)set;
- (void)addObjectsFromOrderedSet:(SCOrderedSet *)orderedSet;
- (void)addSet:(SCOrderedSet *)orderedSet;

Удаление объектов из упорядоченного множества

Для реализации механизма индексного доступа к объектам класс SCOrderedSet дополняет унаследованные от класса SCCollection методы удаления объектов своими собственными методами удаления данных:

- (void)removeFirstObject;
- (void)removeLastObject;
- (void)removeObjectAtIndex:(SCIndex)index;
- (void)removeObjectsAtIndexes:(NSIndexSet *)indexes;
- (void)removeObjectsInRange:(NSRange)range;

Замена объектов упорядоченного множества

В классе SCOrderedSet объявлены следующие методы замены объектов:

- (void)replaceObjectAtIndex:(SCIndex)index withObject:(id<SCCollectioning>)object;
- (void)replaceObjectsAtIndexes:(NSIndexSet *)indexes withObjects:(id<SCCollectioning>)object, ...;
- (void)replaceObjectsAtIndexes:(NSIndexSet *)indexes withCollection:(id<SCCollection>)collection;
- (void)replaceObjectsInRange:(NSRange)range withObjects:(id<SCCollectioning>)object, ...;
- (void)replaceObjectsInRange:(NSRange)range withCollection:(id<SCCollection>)collection;
- (void)setObject:(id<SCCollectioning>)object atIndexedSubscript:(SCIndex)index;

Перемещение объектов упорядоченного множества

Перемещение объектов упорядоченного множества осуществляется следующими методами класса SCOrderedSet:

- (void)exchangeObjectAtIndex:(SCIndex)index withObjectAtIndex:(SCIndex)destination;
- (void)moveObjectAtIndex:(SCIndex)index toIndex:(SCIndex)destination;
- (void)reverse;

Доступ к объектам упорядоченного множества

В классе SCOrderedSet декларированы следующие свойства и методы для доступа к объектам неупорядоченного множества:

@property (nonatomic, readonly, assign) SCOrderedSet *reversedOrderedSet;
@property (nonatomic, readonly, assign) SCArray *allObjects;
@property (nonatomic, readonly, assign) id firstObject;
@property (nonatomic, readonly, assign) id lastObject;
- (id)objectAtIndex:(SCIndex)index;
- (SCArray *)objectsAtIndexes:(NSIndexSet *)indexes;
- (id)objectAtIndexedSubscript:(SCIndex)index;

Поиск объектов упорядоченного множества

Поиск объектов упорядоченного множества осуществляют следующие методы класса SCOrderedSet:

- (SCIndex)indexOfObject:(id<SCCollectioning>)object;
@property (nonatomic, readonly, assign) SCIndex indexOfLastObject;

Комбинирование и рекомбинирование упорядоченных множеств

Упорядоченные множества на базе класса SCOrderedSet предоставляют следующие методы для осуществления операций комбинирования и рекомбинирования:

- (void)unionOrderedSet:(id<SCCollection>)orderedSet;
- (void)unionSet:(id<SCCollection>)set;
- (void)minusOrderedSet:(id<SCCollection>)set;
- (void)minusSet:(id<SCCollection>)set;
- (void)intersectOrderedSet:(id<SCCollection>)orderedSet;
- (void)intersectSet:(id<SCCollection>)set;

Словари

Класс SCDictionary определяет программный интерфейс к хранилищу пар "ключ - значение", доступ к которым осуществляется через ключи, в роли которых выступают текстовые строки. В качестве значений могут использоваться экземпляры классов, поддерживающих коллекции.


Создание словарей

Создание словарей с использованием последовательных файлов, словарей, потоков и объектов данных осуществляются следующими классовыми методами класса SCDictionary:

+ (instancetype)dictionaryWithCoder:(NSCoder *)coder;
+ (instancetype)dictionaryWithContentsOfSerializedFile:(NSString *)path;
+ (instancetype)dictionaryWithDataDictionary:(NSDictionary *)dictionary;
+ (instancetype)dictionaryWithDataDictionaryFromFile:(NSString *)path;
+ (instancetype)dictionaryWithStream:(SCStream *)stream;
+ (instancetype)dictionaryWithFileStream:(NSString *)path;
+ (instancetype)dictionaryWithData:(NSData *)data;
+ (instancetype)dictionaryWithContentsOfFile:(NSString *)path;
+ (instancetype)dictionaryWithContentsOfURL:(NSURL *)url;
+ (instancetype)dictionaryWithContentsOfURLString:(NSString *)urlString;

Создание словарей осуществляется следующими классовыми методами класса SCDictionary:

+ (instancetype)dictionaryWithName:(NSString *)name;
+ (instancetype)dictionaryWithObject:(id<SCCollectioning>)object forKey:(NSString *)key;
+ (instancetype)dictionaryWithObject:(id<SCCollectioning>)object;
+ (instancetype)dictionaryWithObjects:(id<SCCollection>)objects forKeys:(id<SCCollection>)keys;
+ (instancetype)dictionaryWithObjects:(id<SCCollectioning>)object, ...;
+ (instancetype)dictionaryWithObjectsAndKeys:(id<SCCollectioning>)object, ...;
+ (instancetype)dictionaryWithCollection:(id<SCCollection>)collection;
+ (instancetype)dictionaryWithDictionary:(SCDictionary *)dictionary;
+ (instancetype)dictionary;

Инициализация словарей

Также в классе SCDictionary объявлен ряд методов инициализации экземпляров класса:

- (instancetype)initWithName:(NSString *)name;
- (instancetype)initWithObject:(id<SCCollectioning>)object forKey:(NSString *)key;
- (instancetype)initWithObject:(id<SCCollectioning>)object;
- (instancetype)initWithObjects:(id<SCCollection>)objects forKeys:(id<SCCollection>)keys;
- (instancetype)initWithObjects:(id<SCCollectioning>)object, ...;
- (instancetype)initWithObjectsAndKeys:(id<SCCollectioning>)object, ...;
- (instancetype)initWithCollection:(<SCCollection>id)collection;
- (instancetype)initWithDictionary:(SCDictionary *)dictionary;
- (instancetype)init;

Копирование словарей

Класс SCDictionary объявляет следующие методы копирования словарей:

- (void)setDictionary:(SCDictionary *)dictionary;

Сравнение словарей

Для сравнения словарей класс SCDictionary декларирует следующие методы:

- (BOOL)isEqualToDictionary:(SCDictionary *)dictionary;

Получение новых словарей

Класс SCDictionary определяет ряд методов для получения новых словарей с использованием записей из уже существующих словарей:

- (SCDictionary *)dictionaryByAddingObject:(id<SCCollectioning>)object forKey:(NSString *)key;
- (SCDictionary *)dictionaryByAddingObject:(id<SCCollectioning>)object;
- (SCDictionary *)dictionaryByAddingObjects:(id<SCCollection>)objects forKeys:(id<SCCollection>)keys;
- (SCDictionary *)dictionaryByAddingObjects:(id<SCCollectioning>)object, ...;
- (SCDictionary *)dictionaryByAddingObjectsAndKeys:(id<SCCollectioning>)object, ...;
- (SCDictionary *)dictionaryByAddingCollection:(id<SCCollection>)collection;
- (SCDictionary *)dictionaryByAddingObjectsFromArray:(SCArray *)array;
- (SCDictionary *)dictionaryByAddingArray:(SCArray *)array;
- (SCDictionary *)dictionaryByAddingEntriesFromDictionary:(SCDictionary *)dictionary;
- (SCDictionary *)dictionaryByAddingDictionary:(SCDictionary *)dictionary;

Добавление и изменение объектов словаря

Добавление и изменение объектов и значений словаря в классе SCDictionary выполняют следующие методы:

- (void)setObject:(id<SCCollectioning>)object forKey:(NSString *)key;
- (void)setObject:(id<SCCollectioning>)object forKeyedSubscript:(NSString *)key;
- (void)setObjects:(id<SCCollection>)objects forKeys:(id<SCCollection>)keys;
- (void)setObjectsAndKeys:(id<SCCollectioning>)object, ...;
- (void)setValue:(id<SCCollectioning>)value forKey:(NSString *)key;
- (void)setValues:(id<SCCollection>)values forKeys:(id<SCCollection>)keys;
- (void)setValuesAndKeys:(id<SCCollectioning>)object, ...;
- (void)addObjectsFromArray:(SCArray *)array;
- (void)addArray:(SCArray *)array;
- (void)addEntriesFromDictionary:(SCDictionary *)dictionary;
- (void)addDictionary:(SCDictionary *)dictionary;
- (void)addObjects:(id<SCCollection>)objects andKeys:(id<SCCollection>)keys;
- (void)addObjectsAndKeys:(id<SCCollectioning>)object, ...;

Удаление объектов из словаря

Класс SCDictionary объявляет следующие методы удаления данных:

- (void)removeObjectForKey:(NSString *)key;
- (void)removeObjectsForKeys:(id)keys;

Доступ к ключам и значениям словаря

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

@property (nonatomic, readonly, assign) SCArray *allKeys;
@property (nonatomic, readonly, assign) SCArray *allValues;
- (SCArray *)allKeysForObject:(id<SCCollectioning>)object;

Для получения объекта или значения, ассоциированного с конкретным ключем, применяются следующие методы:

- (id)objectForKey:(NSString *)key;
- (id)objectForKeyedSubscript:(NSString *)key;
- (id)valueForKey:(NSString *)key;

Поиск объектов и ключей в словаре

Поиск объектов в словаре осуществляется с помощью следующих методов класса SCDictionary:

- (BOOL)containsObjectForKey:(NSString *)key;
- (BOOL)containsStringForKey:(NSString *)key;
- (BOOL)containsNumberForKey:(NSString *)key;
- (BOOL)containsAnyObjectForKeys:(id<SCCollection>)keys;
- (BOOL)containsAllObjectsForKeys:(id<SCCollection>)keys;

Поиск ключей осуществляется с помощью следующих методов:

- (BOOL)containsKey:(NSString *)key;
- (BOOL)containsKeys:(NSString *)key, ...;
- (BOOL)containsKeysFromCollection:(id<SCCollection>)collection;
- (BOOL)containsAnyKey:(NSString *)key, ...;
- (BOOL)containsAnyKeyFromCollection:(id<SCCollection>)collection;

Счетчики словарей

Свойство keyEnumerator возвращает экземпляр класса NSEnumerator, дающий программисту возможность получить доступ к списку содержащихся в словаре ключей:

@property (nonatomic, readonly, assign) NSEnumerator *keyEnumerator;
[dictionary setObject:@"MacOS" forKey:@"System"];
[dictionary setObject:@"10.11.6" forKey:@"Version"];
[dictionary setBool:NO forKey:@"Debug"];
NSEnumerator *keys = [dictionary keyEnumerator];
NSString *key;
while ( ( key = keys.nextObject)) {
id object = [dictionary objectForKey:key];
NSLog( @"%@: %@", key, object);
}
2016-08-04 14:45:46.853 libtest[20808:3795367] Version: 10.11.6
2016-08-04 14:45:46.853 libtest[20808:3795367] System: MacOS
2016-08-04 14:45:46.853 libtest[20808:3795367] Debug: 0

Стеки

Стеки являются отдельным видом коллекций, представляющим собой список объектов, организованных по принципу LIFO (last in - first out, "последним пришел - первым вышел"). Стек предоставляет доступ только к объекту, добавленному в него последним. Для доступа к остальным объектам необходимо удалить из стека все ранее добавленные объекты.


Создание стеков

Создание стеков из последовательных файлов, словарей, потоков и объектов данных осуществляется с использованием следующих методов класса SCStack:

+ (instancetype)stackWithCoder:(NSCoder *)coder;
+ (instancetype)stackWithContentsOfSerializedFile:(NSString *)path;
+ (instancetype)stackWithDataDictionary:(NSDictionary *)dictionary;
+ (instancetype)stackWithDataDictionaryFromFile:(NSString *)path;
+ (instancetype)stackWithStream:(SCStream *)stream;
+ (instancetype)stackWithFileStream:(NSString *)path;
+ (instancetype)stackWithData:(NSData *)data;
+ (instancetype)stackWithContentsOfFile:(NSString *)path;
+ (instancetype)stackWithContentsOfURL:(NSURL *)url;
+ (instancetype)stackWithContentsOfURLString:(NSString *)urlString;

Для создания стеков класс SCStack объявляет следующие классовые методы:

+ (instancetype)stackWithName:(NSString *)name;
+ (instancetype)stackWithObject:(id<SCCollectioning>)object;
+ (instancetype)stackWithObjects:(id<SCCollectioning>)object, ...;
+ (instancetype)stackWithCollection:(id<SCCollection>)collection;
+ (instancetype)stackWithArray:(SCArray *)array;
+ (instancetype)stackWithStack:(SCStack *)stack;
+ (instancetype)stack;

Инициализация стеков

Класс SCStack декларирует следующие методы инициализации экземпляров класса:

- (instancetype)initWithName:(NSString *)name;
- (instancetype)initWithObject:(id<SCCollectioning>)object;
- (instancetype)initWithObjects:(id<SCCollectioning>)object, ...;
- (instancetype)initWithCollection:(id<SCCollection>)collection;
- (instancetype)initWithArray:(SCArray *)array;
- (instancetype)initWithStack:(SCStack *)stack;
- (instancetype)init;

Копирование стеков

Класс SCStack объявляет следующие методы копирования стеков:

- (void)setStack:(SCStack *)stack;

Сравнение стеков

Для сравнения стеков класс SCStack декларирует следующие методы:

- (BOOL)isEqualToStack:(SCStack *)stack;

Получение новых стеков

Класс SCStack декларирует следующие методы для получения новых стеков с использованием существующих:

- (SCStack *)stackByPushingObject:(id<SCCollectioning>)object;
- (SCStack *)stackByPushingObjects:(id<SCCollectioning>)object, ...;
- (SCStack *)stackByPushingCollection:(id<SCCollection>)collection;
- (SCStack *)stackByPushingObjectsFromArray:(SCArray *)array;
- (SCStack *)stackByPushingArray:(SCArray *)array;
- (SCStack *)stackByPushingObjectsFromStack:(SCStack *)stack;
- (SCStack *)stackByPushingStack:(SCStack *)stack;

Добавление объектов в стек

Класс SCStack для размещения объектов в стеке декларирует следующие методы:

- (void)pushObject:(id<SCCollectioning>)object;
- (void)pushObjects:(id<SCCollectioning>)object, ...;
- (void)pushCollection:(id<SCCollection>)collection;
- (void)pushObjectsFromArray:(SCArray *)array;
- (void)pushArray:(SCArray *)array;
- (void)pushObjectsFromStack:(SCStack *)stack;
- (void)pushStack:(SCStack *)stack;

Извлечение объектов из стека

Для извлечения объектов из стека класс SCStack реализует следующие методы:

- (void)pop;
- (id)popObject;

Удаление объектов из стека

В дополнение к методу pop класс объявляет метод removeTopObject, выполняющий аналогичную функцию. Данный метод введен для логической совместимости с остальными классами коллекций.

- (void)removeTopObject;

Копирование объектов стека

Метод duplicateTopObject дублирует объект, находящийся на вершине стека, то есть последний добавленный объект:

- (void)duplicateTopObject;
SCStack *stack = [SCStack stackWithObjects:@"Object 00", @"Object 01", nil];
NSLog( @"%@", stack);
NSLog( @"%@", stack);
2016-08-08 16:13:06.619 libtest[47645:4720857] Stack count=2: (
"Object 01",
"Object 00"
)
2016-08-08 16:13:06.619 libtest[47645:4720857] Stack count=3: (
"Object 01",
"Object 01",
"Object 00"
)

Доступ к объектам стека

Стек поддерживает прямой доступ только к последнему добавленному в него объекту. Чтобы получить такой доступ, необходимо использовать одно из следующих свойств класса SCStack:

@property (nonatomic, readonly, assign) id topObject;

Очереди

Очередь - вид коллекции, работающей по принципу FIFO (first in - first out, первым пришел - первым ушел). Добавление объектов всегда осуществляется в конец очереди, а извлечение объектов выполняется из начала очереди. Произвольный доступ к объектам, за исключением первого и последнего, очереди не предоставляют, также как не поддерживают изменение порядка следования объектов в очереди.

Реализацию очередей выполняет класс SCQueue, являющийся дочерним для класса SCCollection. Для добавления объектов в очередь применяются унаследованные от класса SCCollection методы добавления, описанные в соответствующем разделе документации.


Создание очередей

Создание очередей из последовательных файлов, словарей, потоков и объектов данных осуществляется следующими классовыми методами:

+ (instancetype)queueWithCoder:(NSCoder *)coder;
+ (instancetype)queueWithContentsOfSerializedFile:(NSString *)path;
+ (instancetype)queueWithDataDictionary:(NSDictionary *)dictionary;
+ (instancetype)queueWithDataDictionaryFromFile:(NSString *)path;
+ (instancetype)queueWithStream:(SCStream *)stream;
+ (instancetype)queueWithFileStream:(NSString *)path;
+ (instancetype)queueWithData:(NSData *)data;
+ (instancetype)queueWithContentsOfFile:(NSString *)path;
+ (instancetype)queueWithContentsOfURL:(NSURL *)url;
+ (instancetype)queueWithContentsOfURLString:(NSString *)urlString;

Класс SCQueue объявляет следующие методы создания очередей:

+ (instancetype)queueWithName:(NSString *)name;
+ (instancetype)queueWithObject:(id<SCCollectioning>)object;
+ (instancetype)queueWithObjects:(id<SCCollectioning>)object, ...;
+ (instancetype)queueWithCollection:(id<SCCollection>)collection;
+ (instancetype)queueWithArray:(SCArray *)array;
+ (instancetype)queueWithQueue:(SCQueue *)queue;
+ (instancetype)queue;

Инициализация очередей

Класс SCQueue объявляет следующие методы инициализации:

- (instancetype)initWithName:(NSString *)name;
- (instancetype)initWithObject:(id<SCCollectioning>)object;
- (instancetype)initWithObjects:(id<SCCollectioning>)object, ...;
- (instancetype)initWithCollection:(id<SCCollection>)collection;
- (instancetype)initWithArray:(SCArray *)array;
- (instancetype)initWithQueue:(SCQueue *)queue;
- (instancetype)init;

Копирование очередей

Класс SCQueue объявляет следующие методы копирования очередей:

- (void)setQueue:(SCQueue *)queue;

Сравнение очередей

Для сравнения очередей класс SCQueue декларирует следующие методы:

- (BOOL)isEqualToQueue:(SCQueue *)queue;

Получение новых очередей

Класс SCQueue реализует следующие методы получения новых очередй на основе существующих очередей:

- (SCQueue *)queueByAddingObject:(id<SCCollectioning>)object;
- (SCQueue *)queueByAddingObjects:(id<SCCollectioning>)object, ...;
- (SCQueue *)queueByAddingCollection:(id<SCCollection>)collection;
- (SCQueue *)queueByAddingObjectsFromArray:(SCArray *)array;
- (SCQueue *)queueByAddingArray:(SCArray *)array;
- (SCQueue *)queueByAddingObjectsFromQueue:(SCQueue *)queue;
- (SCQueue *)queueByAddingQueue:(SCQueue *)queue;

Добавление объектов

Класс SCQueue реализует следующие методы добавления объектов:

- (void)addObjectsFromArray:(SCArray *)array;
- (void)addArray:(SCArray *)array;
- (void)addObjectsFromQueue:(SCQueue *)queue;
- (void)addQueue:(SCQueue *)queue;

Извлечение объектов из очереди

Метод getObject удаляет из очереди первый объект и возвращает на него указатель. Если метод вызван для пустой очереди, то он возвращает пустой указатель.

- (id)getObject;
SCQueue *queue = [SCQueue queueWithObjects:@"Object 00", @"Object 01", @"Object 02", nil];
NSLog( @"%@", queue);
NSLog( @"=====");
id object;
while ( ( object = [queue getObject])) NSLog( @"=> %@", object);
NSLog( @"=====");
NSLog( @"%@", queue);
2016-08-08 17:01:45.115 libtest[48091:4744307] Queue count=3: (
"Object 00",
"Object 01",
"Object 02"
)
2016-08-08 17:01:45.115 libtest[48091:4744307] =====
2016-08-08 17:01:45.115 libtest[48091:4744307] => Object 00
2016-08-08 17:01:45.115 libtest[48091:4744307] => Object 01
2016-08-08 17:01:45.116 libtest[48091:4744307] => Object 02
2016-08-08 17:01:45.116 libtest[48091:4744307] =====
2016-08-08 17:01:45.116 libtest[48091:4744307] Queue count=0:
)

Удаление объектов из очереди

Для удаления объектов из очереди класс SCQueue декларирует следующие методы:

- (void)removeFirstObject;
- (void)removeLastObject;

Копирование объектов очереди

Класс SCQueue объявляет следующие методы для копирования объектов очереди:

- (void)duplicateFirstObject;
- (void)duplicateLastObject;

Доступ к объектам очереди

Для доступа к объектам в очереди класс SCQueue объявляет следующие свойства:

@property (nonatomic, readonly, assign) id firstObject;

Однонаправленные списки

Однонаправленные списки - разновидность коллекций, хранящих данные в форме, при которой информация о следующем объекте хранится вместе с текущим. То есть, доступ к соответствующему объекту возможен только после обработки всех предшестующих ему объектов. Новые объекты добавляются в конец списка. При работе с однонаправленным списком возможен проход только в одном направлении - от предыдущего к следующему (отсюда и название данного вида коллекций).

Работа с объектами однонаправленного списка ограничена доступом к первому объекту списка и к текущему объекту списка (то есть объекту, на который в настоящее время указывает указатель текущего объекта).


Создание списков

Создание списков на основании данных из последовательных файлов, словарей, потоков и объектов данных осуществляется классовыми методами, которые класс SCUnidirectionalList наследует от класса SCList:

+ (instancetype)listWithCoder:(NSCoder *)coder;
+ (instancetype)listWithContentsOfSerializedFile:(NSString *)path;
+ (instancetype)listWithDataDictionary:(NSDictionary *)dictionary;
+ (instancetype)listWithDataDictionaryFromFile:(NSString *)path;
+ (instancetype)listWithStream:(SCStream *)stream;
+ (instancetype)listWithFileStream:(NSString *)path;
+ (instancetype)listWithData:(NSData *)data;
+ (instancetype)listWithContentsOfFile:(NSString *)path;
+ (instancetype)listWithContentsOfURL:(NSURL *)url;
+ (instancetype)listWithContentsOfURLString:(NSString *)urlString;

Для создания экземпляров класса декларируются следующие методы:

+ (instancetype)listWithName:(NSString *)name;
+ (instancetype)listWithObject:(id<SCCollectioning>)object;
+ (instancetype)listWithObjects:(id<SCCollectioning>)object, ...;
+ (instancetype)listWithCollection:(id<SCCollection>)collection;
+ (instancetype)listWithArray:(SCArray *)array;
+ (instancetype)listWithList:(SCList *)list;
+ (instancetype)list;

Инициализация однонаправленных списков

Класс SCUnidirectionalList наследует от класса SCList следующие методы инициализации экземпляров класса:

- (instancetype)initWithName:(NSString *)name;
- (instancetype)initWithObject:(id<SCCollectioning>)object;
- (instancetype)initWithObjects:(id<SCCollectioning>)object, ...;
- (instancetype)initWithCollection:(id<SCCollection>)collection;
- (instancetype)initWithArray:(SCArray *)array;
- (instancetype)initWithList:(SCList *)list;
- (instancetype)init;

Доступ к объектам списка

Класс SCUnidirectionalList наследует от класса SCList следующие свойства доступа к объектам однонаправленного списка:

@property (nonatomic, readonly, assign) id currentObject;
@property (nonatomic, readonly, assign) id firstObject;

Копирование списков

Класс SCUnidirectionalList наследует от класса SCList следующие методы копирования списков:

- (void)setList:(SCList *)list;

Сравнение списков

Для сравнения списков класс SCUnidirectionalList наследует от класса SCList следующие методы:

- (BOOL)isEqualToList:(SCList *)list;

Получение новых списков

Класс SCUnidirectionalList наследует от класса SCList следующие методы для получения новых списков с использованием уже существующих списков:

- (instancetype)listByAddingObject:(id<SCCollectioning>)object;
- (instancetype)listByAddingObjects:(id<SCCollectioning>)object, ...;
- (instancetype)listByAddingCollection:(id<SCCollection>)collection;
- (instancetype)listByAddingObjectsFromArray:(SCArray *)array;
- (instancetype)listByAddingArray:(SCArray *)array;
- (instancetype)listByAddingObjectsFromList:(SCList *)list;
- (instancetype)listByAddingList:(SCList *)list;

Управление списком

Класс SCUnidirectionalList наследует от класса SCList следующие методы управления однонаправленными списками:

- (id)nextObject;

Метод nextObject переводит указатель текущего объекта на следующий объект списка. Если текущий объект был последним в списке, указатель не переводится.

SCUnidirectionalList *list = [SCUnidirectionalList listWithObjects:@"00", @"01", @"02", nil];
NSLog( @"%@", [list currentObject]);
NSLog( @"%@", [list nextObject]);
NSLog( @"%@", [list currentObject]);
2016-08-17 17:30:22.533 libtest[1619:86864] 00
2016-08-17 17:30:22.533 libtest[1619:86864] 01
2016-08-17 17:30:22.533 libtest[1619:86864] 01

Добавление объектов в список

Для вставки объектов перед текущим класс SCUnidirectionalList наследует от класса SCList следующие методы:

- (void)insertCurrentObject:(id<SCCollectioning>)object;
- (void)insertCurrentObjects:(id<SCCollectioning>)object, ...;
- (void)insertCurrentCollection:(id<SCCollection>)collection;

Класс SCUnidirectionalList наследует от класса SCList следующие методы для вставки объектов в начало списка:

- (void)insertFirstObject:(id<SCCollectioning>)object;
- (void)insertFirstObjects:(id<SCCollectioning>)object, ...;
- (void)insertFirstCollection:(id<SCCollection>)collection;

Также класс SCUnidirectionalList наследует от класса SCList следующие методы добавления объектов:

- (void)addObjectsFromArray:(SCArray *)array;
- (void)addArray:(SCArray *)array;
- (void)addObjectsFromList:(SList *)list;
- (void)addList:(SList *)list;

Удаление объектов из списка

Удаление объектов из однонаправленных списков осуществляется следующими унаследованными методами класса:

- (void)removeCurrentObject;
- (void)removeFirstObject;

Замена объектов в списке

Класс SCUnidirectionalList наследует от класса SCList методы, позволяющие заменить текущий или первый объект списка:

- (void)replaceCurrentObjectWithObject:(id<SCCollectioning>)object;
- (void)replaceFirstObjectWithObject:(id<SCCollectioning>)object;

Копирование объектов списка

Для удаления объектов класс SCUnidirectionalList наследует от класса SCList следующие методы:

- (void)duplicateCurrentObject;
- (void)duplicateFirstObject;

Двунаправленные списки

Двунаправленный список во многом аналогичен однонаправленному списку, однако указатель в нем может смещаться в обоих направлениях (как от начала к концу списка, так и от конца списка к его началу), а не в одном, как у однонаправленного списка. Кроме этого, двунаправленный список предоставляет доступ к последнему объекту списка. Также в данном разделе мы приведем описание методов, объявленных непосредственно в классе SCBidirectionalList.


Доступ к объектам списка

Доступ к объектам двунаправленного списка обеспечивают следующие свойства класса SCBidirectionalList:

@property (nonatomic, readonly, assign) id lastObject;

Свойство lastObject возвращает указатель на последний объект двунаправленного списка. Если список пуст, свойство возвращает пустой указатель.


Управление списком

Для управления двунаправленными списками класс SCBidirectionalList декларирует следующие методы:

- (id)previousObject;

Метод previousObject передвигает указатель текущего объекта на предыдущий элемент списка и возвращает указатель на новый текущий объект. Если метод вызван для первого объекта списка, то метод возвращает нулевой указатель, но не меняет указатель текущего объекта:

SCBidirectionalList *list = [SCBidirectionalList listWithObjects:@"00", @"01", @"02", nil];
do { } while ( [list nextObject]);
do {
NSLog( @"%@", [list currentObject]);
} while ( [list previousObject]);
2016-08-17 21:07:59.306 libtest[3279:182111] 02
2016-08-17 21:07:59.306 libtest[3279:182111] 01
2016-08-17 21:07:59.306 libtest[3279:182111] 00

Добавление объектов в список

Для добавления объектов класс SCBidirectionalList декларирует методы:

- (void)insertLastObject:(id<SCCollectioning>)object;
- (void)insertLastObjects:(id<SCCollectioning>)object, ...;
- (void)insertLastCollection:(id<SCCollection>)collection;

Удаление объектов из списка

Класс SCBidirectionalList декларирует следующие методы удаления объектов из списка:

- (void)removeLastObject;

Метод removeLastObject удаляет из двунаправленного списка последний объект:

SCBidirectionalList *list = [SCBidirectionalList listWithObjects:@"00", @"01", @"02", nil];
NSLog( @"%@", list);
NSLog( @"%@", list);
2016-08-17 21:15:38.556 libtest[3382:184602] List count=3: (
"00",
"01",
"02"
)
Current object: "00"
2016-08-17 21:15:38.557 libtest[3382:184602] List count=2: (
"00",
"01"
)
Current object: "00"

Замена объектов списка

Для осуществления замены объектом класс SCBidirectionalList объявляет следующие методы:

- (void)replaceLastObjectWithObject:(id<SCCollectioning>)object;

Метод replaceLastObjectWithObject: заменяет последний объект двунаправленного списка заданным объектом:

SCBidirectionalList *list = [SCBidirectionalList listWithObjects:@"00", @"01", @"02", nil];
NSLog( @"%@", list);
NSLog( @"%@", list);
2016-08-17 21:20:48.686 libtest[3422:186097] List count=3: (
"00",
"01",
"02"
)
Current object: "00"
2016-08-17 21:20:48.686 libtest[3422:186097] List count=3: (
"00",
"01",
"=="
)
Current object: "00"

Копирование объектов списка

Копирование объектов двунаправленного списка осуществляется следующими методами:

- (void)duplicateLastObject;

Метод duplicateLastObject копирует последний объект двунаправленного списка:

SCBidirectionalList *list = [SCBidirectionalList listWithObjects:@"00", @"01", @"02", nil];
NSLog( @"%@", list);
NSLog( @"%@", list);
2016-08-17 21:22:27.623 libtest[3448:186559] List count=3: (
"00",
"01",
"02"
)
Current object: "00"
2016-08-17 21:22:27.623 libtest[3448:186559] List count=4: (
"00",
"01",
"02",
"02"
)
Current object: "00"

Сортировщики

Коллекции, которые поддерживают прямой доступ к объектам (массивы и упорядоченные множества), также поддерживают сортировку своих элементов. Однако сами коллекции данных типов алгоритмов сортировки не реализуют. Такой подход связан с тем, что в настоящее время известно множество таких алгоритмов, а в будущем возможна разработка новых, и нет смысла тратить время и ресурсы на реализацию в библиотеке их всех. Но в то же время необходима возможность по добавлению новых алгоритмов сортировки.

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


Протокол и класс SCSorter

Совместимые с библиотекой сортировщики должны соответствовать протоколу SCSorter. Данный протокол объявляет обязательными реализацию сортировщиком следующих методов:

- (void)ascendingSortCollection:(id<SCMutableIndexedCollection>)collection;
- (void)descendingSortCollection:(id<SCMutableIndexedCollection>)collection;
- (void)ascendingSortText:(SCStrings *)text;
- (void)descendingSortText:(SCStrings *)text;

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

Класс SCSorter является полной реализацией протокола SCSorter и введет для удобства последующей реализации новых классов сортировки данных. В настоящее время в состав библитеки входят два дочерних класса, предоставляющих готовые алгоритмы сортировки:

Данные классы описаны в следующих параграфах нашей документации.


Сортировщик SCBubbleSorter

Класс SCBubbleSorter реализует один из самых простых и известных алгоритмов сортировки, известный под названием "пузырька" или "пузырьковой сортировки". Главный недостаток алгоритма - его низкая скорость. В классе объявлен только один классовый метод, отвечающий за создание сортировщика:

+ (instancetype)sorter;

Сортировщик SCFastSorter

Класс SCFastSorter обеспечивает реализацию известного алгоритма быстрой сортировки. Данный алгоритм является сортировщиком по умолчанию для коллекций библиотеки. В классе декларирован только один метод создания сортировщика:

+ (instancetype)sorter;

Коллекции и стандартные классы

Библиотека реализует определенную (но не полную совместимость) коллекций и стандартных классов Objective C. Частичная совместимость может быть условно разделена на следующие группы:

Все библиотечные классы имеют ряд общих отличий от стандартных классов:


Обработка ошибок при работе с коллекциями

При работе c коллекциями могут возникать различные ошибки. В данном разделе мы опишем процедуру их обработки механизмом коллекций.

Если коллекция обнаруживает возникновение той или иной ошибки, она прежде всего проверяет, назначен ли объект делегирования (описан в следующем разделе документации). Если таковой объект не назначен, выполняется генерация исключительной ситуации SCCollectionException.

Если объект делегирования назначен, то коллекция вызывает его метод collection:didDetectException:. В том случае, если данный метод возвращает значение YES, то коллекция игнорирует возникшую ошибку. В противном случае коллекция генерирует исключительную ситуацию SCCollectionException.

Подробности о конкретных ошибках коллекций приведены в разделе Ошибки коллекций. В данном разделе мы приведем описание основных ошибок коллекций:


Протокол делегирования SCCollectionDelegate

Для реагирования на различные события в классах коллекций программист может назначить объект делегирования через присвоение значения свойству delegate.

Объектом делегирования может быть экземпляр любого класса, который соответствует протоколу SCCollectionDelegate или унаследован от класса SCCollectionDelegate (входящий в состав библиотеки класс, реализующий данный протокол).

Ниже мы рассмотрим различные методы протокола и опишем события, при наступлении которых они вызываются:


Обработка ошибок коллекций

Протокол SCCollectionDelegate определяет следующие методы обработки ошибок:

- (BOOL)collection:(SCCollection *)collection didDetectException:(SCCollectionException *)exception;

События добавления элементов

Протокол SCCollectionDelegate определяет ряд методов, вызываемых в ходе выполнения операций добавления объектов в коллекцию:

- (void)collection:(SCCollection *)collection willAddObject:(id)object;
- (void)collection:(SCCollection *)collection willInsertObject:(id)object atIndex:(SCIndex)index;
- (void)collection:(SCCollection *)collection willSetObject:(id)object forKey:(NSString *)key;
- (void)collection:(SCCollection *)collection willSetValue:(id)value forKey:(NSString *)key;
- (void)collection:(SCCollection *)collection didFinishAddingObject:(id)object;
- (void)collection:(SCCollection *)collection didFinishInsertingObject:(id)object atIndex:(SCIndex)index;
- (void)collection:(SCCollection *)collection didFinishSettingObject:(id)object forKey:(NSString *)key;
- (void)collection:(SCCollection *)collection didFinishSettingValue:(id)value forKey:(NSString *)key;

События удаления элементов

Удаление объектов из коллекций сопровождается вызовами следующих методов протокола SCCollectionDelegate:

- (void)willRemoveAllObjectsFromCollection:(SCCollection *)collection;
- (void)collection:(SCCollection *)collection willRemoveObjectsOfClassName:(NSString *)name;
- (void)collection:(SCCollection *)collection willRemoveObject:(id)object;
- (void)collection:(SCCollection *)collection willRemoveObjectAtIndex:(SCIndex)index;
- (void)collection:(SCCollection *)collection willRemoveObjectForKey:(NSString *)key;
- (void)didFinishRemovingAllObjectsFromCollection:(SCCollection *)collection;
- (void)collection:(SCCollection *)collection didFinishRemovingObjectsOfClassName:(NSString *)name;
- (void)collection:(SCCollection *)collection didFinishRemovingObject:(id)object;
- (void)collection:(SCCollection *)collection didFinishRemovingObjectAtIndex:(SCIndex)index;
- (void)collection:(SCCollection *)collection didFinishRemovingObjectForKey:(NSString *)key;

Обработка элементов коллекций

Протокол SCCollectionDelegate определяет методы обработки элементов коллекции:

- (void)processObject:(id)object collection:(SCCollection *)collection;

Сортировка данных

При выполнении сортировки объектов коллекции вызываются следующие методы протокола SCCollectionDelegate:

- (void)collection:(SCCollection *)collection willSortAscending:(BOOL)ascending sorter:(id<SCSorter>)sorter;
- (void)collection:(SCCollection *)collection didFinishSortingAscending:(BOOL)ascending sorter:(id<SCSorter>)sorter;

Замена элементов коллекции

Для обработки событий, связанных с заменой объектов в коллекциях, протокол SCCollectionDelegate декларирует следующие методы:

- (void)collection:(SCCollection *)collection willReplaceObjectAtIndex:(SCIndex)index withObject:(id)object;
- (void)collection:(SCCollection *)collection willReplaceObjectsInRange:(NSRange)range withCollection:(id)source;
- (void)collection:(SCCollection *)collection willReplaceObject:(id)replaced withObject:(id)object;
- (void)collection:(SCCollection *)collection didFinishReplacingObjectAtIndex:(SCIndex)index withObject:(id)object;
- (void)collection:(SCCollection *)collection didFinishReplacingObjectsInRange:(NSRange)range withCollection:(id)source;
- (void)collection:(SCCollection *)collection didFinishReplacingObject:(id)replaced withObject:(id)object;

Копирование и перемещение элементов коллекции

События копирования и перемещения объектов в коллекциях приводят к вызовам следующих методов протокола SCCollectionDelegate:

- (void)collection:(SCCollection *)collection willExchangeObjectAtIndex:(SCIndex)index
withObjectAtIndex:(SCIndex)destination;
- (void)collection:(SCCollection *)collection didFinishExchangingObjectAtIndex:(SCIndex)index
withObjectAtIndex:(SCIndex)destination;

Списки строк, тексты и текстовые файлы

В состав библиотеки входит ряд классов, обеспечивающих обработку текстовой информации различного вида:

На приведенной ниже схеме данные классы изображены в виде иерархии.

text.png

Отдельные главы раздела рассматривают также ряд связанных с текстами дополнительных вопросов:


Списки строк

Как следует из названия, список строк представляет собой совокупность текстовых строк, объединяемых в одном экземпляре класса SCStrings. Кроме непосредственно хранения, список обеспечивает базовые методы для работ ы с содержащимися в ней строками - добавления, удаления, изменения, перемещения в пределах списка и так далее.

Класс SCStrings является базовым для иерархии текстовых классов, различным образом расширяющих функциональность своего базового класса. Данная глава посвящена классу SCStrings, а его потомки описываются в следующих главах руководства.


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

Как и все классы библиотеки, SCStrings объявляет классовые методы для создания экземпляров класса на основании данных из последовательных файлов, словарей, потоков и объектов данных:

+ (instancetype)stringsWithCoder:(NSCoder *)coder;
+ (instancetype)stringsWithContentsOfSerializedFile:(NSString *)path;
+ (instancetype)stringsWithDataDictionary:(NSDictionary *)dictionary;
+ (instancetype)stringsWithDataDictionaryFromFile:(NSString *)path;
+ (instancetype)stringsWithStream:(SCStream *)stream;
+ (instancetype)stringsWithFileStream:(NSString *)path;
+ (instancetype)stringsWithData:(NSData *)data;
+ (instancetype)stringsWithContentsOfFile:(NSString *)path;
+ (instancetype)stringsWithContentsOfURL:(NSURL *)url;
+ (instancetype)stringsWithContentsOfURLString:(NSString *)urlString;

Создать экземпляр класса можно с использованием ряда классовых методов:

+ (instancetype)stringsWithName:(NSString *)name;
+ (instancetype)stringsWithString:(NSString *)string;
+ (instancetype)stringsWithCollection:(id<SCCollection>)collection;
+ (instancetype)stringsWithArray:(SCArray *)array;
+ (instancetype)stringsWithStrings:(SCStrings *)strings;
+ (instancetype)strings;

Инициализация списков строк

Класс SCStrings объявляет следующие инициализаторы экземпляров класса:

- (instancetype)initWithName:(NSString *)name;
- (instancetype)initWithString:(NSString *)string;
- (instancetype)initWithCollection:(id<SCCollection>)collection;
- (instancetype)initWithArray:(SCArray *)array;
- (instancetype)initWithStrings:(SCStrings *)strings;
- (instancetype)init;

Свойства экземпляра класса

Класс SCStrings декларирует следующие основные свойства экземпляров класса:

@property (nonatomic, readwrite, retain) NSString *name;
@property (nonatomic, readonly, assign) SCIndex count;
@property (nonatomic, readwrite, assign) BOOL readOnly;
@property (nonatomic, readonly, assign) BOOL empty;
@property (nonatomic, readonly, assign) BOOL modified;
@property (nonatomic, readwrite, assign) BOOL caseInsensitive;
@property (nonatomic, readwrite, retain) id<SCTextDelegate> delegate;

Копирование списков строк

Для осуществления операций копирования списков строк класс SCStrings декларирует следующие методы:

- (void)setStrings:(SCStrings *)strings;
- (void)setCollection:(id<SCCollection>)collection;
- (void)setString:(NSString *)string;

Сравнение списков строк

Для сравнения списков строк класс SCStrings объявляет следующие методы:

- (BOOL)isEqualToStrings:(SCStrings *)strings;
- (BOOL)isEqualToCollection:(id<SCCollection>)collection;

Получение новых списков строк

Класс SCStrings объявляет следующие методы для получения новых списков строк с использованием существующих списков строк:

- (instancetype)stringsByAddingString:(NSString *)string;
- (instancetype)stringsByAddingCollection:(id<SCCollection>)collection;
- (instancetype)stringsByAddingStrings:(SCStrings *)strings;
- (instancetype)stringsByAddingStringsFromArray:(SCArray *)array;
- (instancetype)stringsByAddingArray:(SCArray *)array;

Счетчики строк

Для доступа к счетчикам строк класс SCStrings предоставляет следующие свойства и методы:

@property (nonatomic, readonly, assign) NSEnumerator *stringEnumerator;
@property (nonatomic, readonly, assign) NSEnumerator *reverseStringEnumerator;
- (void)enumerateWithDelegate:(id<SCTextDelegate>)delegate;
- (void)enumerate;
- (void)reverseEnumerateWithDelegate:(id<SCTextDelegate>)delegate;
- (void)reverseEnumerate;

Кроме вышеперечисленных свойств класс SCStrings реализует метод, обеспечивающий поддержку оператора for..in:

- (NSUInteger)countByEnumeratingWithState:(NSFastEnumerationState *)state objects:(id *)buffer count:(NSUInteger)count;
[list addString:@"First string"];
[list addString:@"Second string"];
[list addString:@"Last string"];
for ( NSString *string in list) NSLog( @"%@", string);
2017-09-10 21:48:48.625693+0300 libtest[5836:158623] First string
2017-09-10 21:48:48.625713+0300 libtest[5836:158623] Second string
2017-09-10 21:48:48.625725+0300 libtest[5836:158623] Last string

Преобразование списков строк

Класс SCStrings декларирует ряд свойств для преобразования списка строк в другие форматы данных:

@property (nonatomic, readonly, assign) SCArray *array;
@property (nonatomic, readonly, retain) NSArray *foundationArray;

Сортировка строк

Класс SCStrings объявляет ряд свойств и методов сортировки строк:

- (void)sortAscendingWithSorter:(id<SCSorter>)sorter;
- (void)sortDescendingWithSorter:(id<SCSorter>)sorter;
- (void)sortWithSorter:(id<SCSorter>)sorter;
- (void)sortAscending;
- (void)sortDescending;
- (void)sort;
- (SCStrings *)ascendingSortedStringsWithSorter:(id<SCSorter>)sorter;
- (SCStrings *)descendingSortedStringsWithSorter:(id<SCSorter>)sorter;
- (SCStrings *)sortedStringsWithSorter:(id<SCSorter>)sorter;
@property (nonatomic, readonly, assign) SCStrings *ascendingSortedStrings;
@property (nonatomic, readonly, assign) SCStrings *descendingSortedStrings;
@property (nonatomic, readonly, assign) SCStrings *sortedStrings;
Внимание
При попытке вызвать любой из вышеперечисленных методов для списка строк в режиме "только для чтения" генерируется ошибка SCL-20063.
Внимание
Сортировка строк зависит от режима регистронезависимости списка строк.

В ходе работы данных методов вызываются обработчики событий text:willSortAscending:sorter: и text:didFinishSortingAscending:sorter: протокола SCTextDelegate.


Добавление строк

Если описанные в данном параграфе методы вызываются для списка строк, находящегося в режиме "только для чтения", происходит генерация исключительной ситуации SCL-20063.

Добавление строк в конец списка осуществляется следующими методами класса SCStrings:

- (void)addString:(NSString *)string;
- (void)addCollection:(id<SCCollection>)collection;
- (void)addStrings:(SCStrings *)strings;
- (void)addLine;
- (void)addStringsFromArray:(SCArray *)array;
- (void)addArray:(SCArray *)array;

При работе данных методов осуществляется вызов событий text:willAddString: и text:didFinishAddingString: объекта делегирования, соответствующего протоколу SCTextDelegate.

Кроме операций добавления строк в конец списка класс SCStrings декларирует ряд методов для вставки новых строк по указанным позициям:

- (void)insertString:(NSString *)string atIndex:(SCIndex)index;
- (void)insertStrings:(SCStrings *)strings atIndex:(SCIndex)index;
- (void)insertCollection:(id<SCCollection>)collection atIndex:(SCIndex)index;
- (void)insertStrings:(SCStrings *)strings atIndexes:(NSIndexSet *)indexes;
- (void)insertCollection:(id<SCCollection>)collection atIndexes:(NSIndexSet *)indexes;
- (void)insertLineAtIndex:(SCIndex)index;

Работа методов вставки строк сопровождается вызовами обработчиков событий text:willInsertString:atIndex: и text:didFinishInsertingString:atIndex: объекта делегирования списка строк.


Удаление строк

Класс SCStrings декларирует большое количество методов удаления строк по различным критериям:

- (void)removeAllStrings;
- (void)removeFirstString;
- (void)removeLastString;
- (void)removeStringAtIndex:(SCIndex)index;
- (void)removeStringsAtIndexes:(NSIndexSet *)indexes;
- (void)removeString:(NSString *)string;
- (void)removeStrings:(SCStrings *)strings;
- (void)removeCollection:(id<SCCollection>)collection;
- (void)removeStringsWithSubstring:(NSString *)substring;
- (void)removeStringsNotAtIndexes:(NSIndexSet *)indexes;
- (void)removeStringsNotEqualTo:(NSString *)string;
- (void)removeStringsNotInStrings:(SCStrings *)strings;
- (void)removeStringsNotInCollection:(id<SCCollection>)collection;
- (void)removeStringsWithoutSubstring:(NSString *)substring;
- (void)removeDuplicatedStrings;

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

В ходе выполнения данных методов класс SCStrings вызывает обработчики событий text:willRemoveStringAtIndex: и text:didFinishRemovingStringAtIndex: объекта делегирования экземпляра класса.

Вышеперечисленные методы вызывают обработчики событий text:willRemoveString: и text:didFinishRemovingString: объекта делегирования списка строк.

Описанные выше методы вызывают обработчики событий text:willRemoveStringAtIndex: и text:didFinishRemovingStringAtIndex: объекта делегирования, соответствующего протоколу SCTextDelegate.


Замена строк

Класс SCStrings определяет ряд методов для осуществления замены строк:

- (void)replaceStringAtIndex:(SCIndex)index withString:(NSString *)string;
- (void)replaceStringsAtIndexes:(NSIndexSet *)indexes withStrings:(SCStrings *)strings;
- (void)replaceStringsAtIndexes:(NSIndexSet *)indexes withCollection:(id<SCCollection>)collection;
- (void)replaceString:(NSString *)string withString:(NSString *)newString;

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

Все эти методы в ходе своей работы вызывают обработчики событий text:willReplaceStringAtIndex:withString: и text:didFinishReplacingStringAtIndex:withString: объекта делегирования соответствующего списка строк.

Кроме вышеперечисленных методов класс SCStrings обеспечивает поддержку оператора [] для замены строк с использованием их индекса:

[strings addString:@"First string"];
[strings addString:@"Second string"];
[strings addString:@"Last string"];
NSLog( @"%@", strings);
strings[1] = @"New string";
NSLog( @"%@", strings);
2017-09-11 12:47:49.626863+0300 libtest[15505:479454] Strings list count=3, case sensitive, modified: (
First string
Second string
Last string
)
2017-09-11 12:47:49.626967+0300 libtest[15505:479454] Strings list count=3, case sensitive, modified: (
First string
New string
Last string
)

Копирование и перемещение строк

Класс SCStrings является не просто контейнером для хранения различных строк, но и предоставляет достаточно мощные средства для построчной обработки своего содержимого. К этим средствам относятся такие методы класса, как:

- (void)exchangeStringAtIndex:(SCIndex)index withStringAtIndex:(SCIndex)destination;
- (void)duplicateStringAtIndex:(SCIndex)index;
- (void)duplicateAllStrings;
- (void)duplicate;
- (void)copyStringAtIndex:(SCIndex)index toIndex:(SCIndex)destination;
- (void)moveStringAtIndex:(SCIndex)index toIndex:(SCIndex)destination;
- (void)forwardMoveStringAtIndex:(SCIndex)index steps:(SCIndex)steps;
- (void)forwardMoveStringAtIndex:(SCIndex)index;
- (void)backwardMoveStringAtIndex:(SCIndex)index steps:(SCIndex)steps;
- (void)backwardMoveStringAtIndex:(SCIndex)index;
- (void)moveToFirstPositionStringAtIndex:(SCIndex)index;
- (void)moveToLastPositionStringAtIndex:(SCIndex)index;

Обращаем внимание, что вызов любого из этих методов для находящегося в режиме "только для чтения" списка строк вызывает генерацию исключительной ситуации SCL-20063. Кроме этой ошибки возможно возникновение и других ошибок, характерных как для всей группы методов, так и для конкретных методов. При рассмотрении методов мы будем указывать на исключительные ситуации, которые могут возникнуть в ходе работы.

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

@property (nonatomic, readonly, assign) SCStrings *reversedStrings;
- (void)reverse;

Доступ к строкам

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

@property (nonatomic, readonly, assign) NSString *firstString;
@property (nonatomic, readonly, assign) NSString *lastString;
- (NSString *)firstString;
- (NSString *)lastString;
- (NSString *)stringAtIndex:(SCIndex)index;
- (SCStrings *)stringsAtIndexes:(NSIndexSet *)indexes;

Также класс SCStrings реализует поддержку доступа к строкам с использованием оператора [] и индексов строк:

[strings addString:@"First string"];
[strings addString:@"Second string"];
[strings addString:@"Last string"];
NSLog( @"%@", strings[1]);
2017-09-11 12:58:11.386036+0300 libtest[15714:487455] Second string

Поиск строк

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

При осуществлении операций поиска список строк учитывает значение свойства caseInsensitive. Если это свойство установлено в NO, то список строк игнорирует разницу в регистре символом.

Для выполнения проверок на наличие строк по различным критериям класс SCStrings декларирует следующие методы:

- (BOOL)containsString:(NSString *)string;
- (BOOL)containsStrings:(SCStrings *)strings;
- (BOOL)containsCollection:(id<SCCollection>)collection;
- (BOOL)containsAnyString:(SCStrings *)strings;
- (BOOL)containsAnyStringFromCollection:(id<SCCollection>)collection;
- (BOOL)containsSubstring:(NSString *)substring;
- (BOOL)containsSubstrings:(SCStrings *)substrings;
- (BOOL)containsSubstringsFromCollection:(id<SCCollection>)collection;
- (BOOL)containsAnySubstring:(SCStrings *)substrings;
- (BOOL)containsAnySubstringFromCollection:(id<SCCollection>)collection;
- (BOOL)containsDuplicatedStrings;

Для определения индексов строк класс SCStrings объявляет следующие свойства и методы:

@property (nonatomic, readonly, assign) SCIndex indexOfLastString;
- (SCIndex)indexOfString:(NSString *)string;
- (SCIndex)indexOfLastString;
- (SCIndex)indexOfSubstring:(NSString *)substring;

Выборка строк - это процесс формирования нового списка строк на основании каких-либо критериев отбора исходных строк. Класс SCStrings предоставляет широкий набор методов выборки, декларируя их следующим образом:

- (SCStrings *)stringsWithSubstring:(NSString *)substring;
- (SCStrings *)stringsWithSubstrings:(SCStrings *)substrings;
- (SCStrings *)stringsWithSubstringsFromCollection:(id<SCCollection>)collection;
- (SCStrings *)stringsWithAnySubstring:(SCStrings *)substrings;
- (SCStrings *)stringsWithAnySubstringFromCollection:(id<SCCollection>)collection;
- (SCStrings *)stringsWithoutSubstring:(NSString *)substring;
- (SCStrings *)stringsWithoutSubstrings:(SCStrings *)substrings;
- (SCStrings *)stringsWithoutSubstringsFromCollection:(id<SCCollection>)collection;

Подсчет строк осуществляется следующими методами класса SCStrings:

- (SCULong)countOfString:(NSString *)string;
- (SCULong)countOfSubstring:(NSString *)substring;
- (SCULong)countOfStringsWithSubstring:(NSString *)substring;

Списки уникальных строк

Класс SCUniqueStrings наследует от класса SCStrings всю функциональность списка строк, дополняя его средствами контроля за уникальностью добавляемой в список информации - списки уникальных строк не допускают дублирования хранящихся в них строках. Попытка добавить строку, которая уже присутствует в таком списке, в зависимости от значения свойства strongMode приводит либо к игнорированию добавляемой строки, либо вызывает генерацию исключительной ситуации SCL-20069 с указанием, какую из существующих строк дублирует новая.

Естественно, что унаследованные от класса SCStrings методы по копированию и дублированию строк в классе SCUniqueStrings перекрыты и также либо игнорируются, либо вызывают исключительную ситуацию SCL-20069.

Особо отметим, что как и класс-предок, SCUniqueStrings в зависимости от значения свойства caseInsensitive либо учитывает, либо не учитывает регистр символов. Важным моментом является поведение экземпляра класса при переключении значения этого свойства из NO в YES. При таком переключении может возникнуть ситуация, когда ранее считавшиеся разными строки в новом режиме будут признаны одинаковыми и либо строки с большими индексами будут удалены, либо будет сгенерирована исключительная ситуация SCL-20069.

strings.caseInsensitive = NO;
[strings addString:@"String 00"];
[strings addString:@"string 00"];
strings.caseInsensitive = YES;
2016-08-25 11:30:46.520 libtest[12212:1075882] SCL-20069: Duplicate string "string 00" at index 1
2016-08-25 11:30:46.520 libtest[12212:1075882] ==================================================

Поэтому мы рекомендуем с осторожностью изменять режим регистрозависимости для непустых списков уникальных строк.

При копировании данных из существующих обычных списков строк и коллекций дублирующие строки также будут либо удалены, либо будет сгенерирована ошибка.


Свойства экземпляров класса

В дополнение к унаследованным от предка свойствам класс SCUniqueStrings декларирует собственные свойства:

@property (nonatomic, readwrite, assign) BOOL strongMode;

Создание списков уникальных строк

Для создания списков уникальных строк на основании данных из последовательных файлов, словарей, потоков и объектов данных класс SCUniqueStrings декларирует следующие классовые методы:

+ (instancetype)uniqueStringsWithCoder:(NSCoder *)coder;
+ (instancetype)uniqueStringsWithContentsOfSerializedFile:(NSString *)path;
+ (instancetype)uniqueStringsWithDataDictionary:(NSDictionary *)dictionary;
+ (instancetype)uniqueStringsWithDataDictionaryFromFile:(NSString *)path;
+ (instancetype)uniqueStringsWithStream:(SCStream *)stream;
+ (instancetype)uniqueStringsWithFileStream:(NSString *)path;
+ (instancetype)uniqueStringsWithData:(NSData *)data;
+ (instancetype)uniqueStringsWithContentsOfFile:(NSString *)path;
+ (instancetype)uniqueStringsWithContentsOfURL:(NSURL *)url;
+ (instancetype)uniqueStringsWithContentsOfURLString:(NSString *)urlString;

Создание экземпляров класса SCUniqueStrings осуществляется следующими классовыми методами:

+ (instancetype)uniqueStringsWithName:(NSString *)name;
+ (instancetype)uniqueStringsWithString:(NSString *)string;
+ (instancetype)uniqueStringsWithCollection:(id<SCCollection>)collection;
+ (instancetype)uniqueStringsWithArray:(SCArray *)array;
+ (instancetype)uniqueStringsWithStrings:(SCStrings *)strings;
+ (instancetype)uniqueStringsWithUniqueStrings:(SCUniqueStrings *)uniqueStrings;
+ (instancetype)uniqueStrings;

Инициализация списков уникальных строк

Кроме унаследованных от SCStrings методов инициализации класс SCUniqueStrings объявляет собственные методы:

- (instancetype)initWithUniqueStrings:(SCUniqueStrings *)uniqueStrings;

Копирование списков

Класс SCUniqueStrings дополняет унаследованные методы копирования экземпляров класса следующими собственными методами:

- (void)setUniqueStrings:(SCUniqueStrings *)uniqueStrings;

Сравнение списков

Класс CSUniqueStrings дополняет унаследованные методы сравнения следующими собственными методами:

- (BOOL)isEqualToUniqueStrings:(SCUniqueStrings *)uniqueStrings;

Преобразование списков

Класс SCUniqueStrings дополняет унаследованные свойства преобразования следующими собственными свойствами:

@property (nonatomic, readonly, assign) SCStrings *strings;
@property (nonatomic, readonly, assign) SCOrderedSet *orderedSet;
@property (nonatomic, readonly, assign) NSOrderedSet *foundationOrderedSet;

Получение новых списков уникальных строк

Класс SCUniqueStrings реализует следующие методы для создания новых списков уникальных строк с использованием уже существующих списков уникальных строк:

- (instancetype)uniqueStringsByAddingString:(NSString *)string;
- (instancetype)uniqueStringsByAddingCollection:(id<SCCollection>)collection;
- (instancetype)uniqueStringsByAddingStringsFromArray:(SCArray *)array;
- (instancetype)uniqueStringsByAddingArray:(SCArray *)array;
- (instancetype)uniqueStringsByAddingStrings:(SCStrings *)strings;
- (instancetype)uniqueStringsByAddingUniqueStrings:(SCUniqueStrings *)uniqueStrings;

Тексты

Класс SCText расширяет функциональные возможности класса SCStrings, добавляя к спискам строк методы для работы с текстовыми блоками - группами строк внутри списков строк. SCText обеспечивает выполнение таких операций, как добавление, вставка, удаление, копирование, перемещение и так далее. Именно данная дополнительная функциональность и делает из простого списка строк текст в том виде, в каком мы привыкли работать с текстами в текстовых редакторах.

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


Создание текстов

Класс SCText декларирует следующие классовые методы для создания экземпляров класса на основании данных из последовательных файлов, словарей, потоков, и объектов данных:

+ (instancetype)textWithCoder:(NSCoder *)coder;
+ (instancetype)textWithContentsOfSerializedFile:(NSString *)path;
+ (instancetype)textWithDataDictionary:(NSDictionary *)dictionary;
+ (instancetype)textWithDataDictionaryFromFile:(NSString *)path;
+ (instancetype)textWithStream:(SCStream *)stream;
+ (instancetype)textWithFileStream:(NSString *)path;
+ (instancetype)textWithData:(NSData *)data;
+ (instancetype)textWithContentsOfFile:(NSString *)path;
+ (instancetype)textWithContentsOfURL:(NSURL *)url;
+ (instancetype)textWithContentsOfURLString:(NSString *)urlString;

Для создания текстов могут быть использованы следующие классовые методы SCText:

+ (instancetype)textWithName:(NSString *)name;
+ (instancetype)textWithString:(NSString *)string;
+ (instancetype)textWithStrings:(SCStrings *)strings;
+ (instancetype)textWithCollection:(id<SCCollection>)collection;
+ (instancetype)textWithArray:(SCArray *)array;
+ (instancetype)textWithText:(SCText *)text;
+ (instancetype)text;

Инициализация текстов

Класс SCText дополняет инициализаторы родительского класса следующими методами:

- (instancetype)initWithText:(SCText *)text;

Копирование текстов

Класс SCText дополняет класс SCStrings следующими методами копирования:

- (void)setText:(SCText *)text;

Сравнение текстов

Класс SCText декларирует следующие методы сравнения экземпляров класса:

- (BOOL)isEqualToText:(SCText *)text;

Получение новых текстов

Класс SCText декларирует ряд методов для получения текстов на основе существующих текстов:

- (instancetype)textByAddingString:(NSString *)string;
- (instancetype)textByAddingCollection:(id<SCCollection>)collection;
- (instancetype)textByAddingStringsFromArray:(SCArray *)array;
- (instancetype)textByAddingArray:(SCArray *)array;
- (instancetype)textByAddingStrings:(SCStrings *)strings;
- (instancetype)textByAddingText:(SCText *)text;

Преобразование текстов

Класс SCText дополняет класс SCStrings следующими свойствами для преобразования текстов:

@property (nonatomic, readonly, assign) SCStrings *strings;
@property (nonatomic, readonly, assign) SCUniqueStrings *uniqueStrings;

Добавление текста

Класс SCText декларирует следующие методы добавления текстов:

- (void)addText:(SCStrings *)text;
- (void)insertText:(SCStrings *)text atIndex:(SCIndex)index;

Удаление текста

Класс SCText объявляет ряд методов для удаления текстовых блоков:

- (void)removeAllText;
- (void)removeTextInRange:(NSRange)range;
- (void)removeTextWithSubstring:(NSString *)substring;
- (void)removeTextWithoutSubstring:(NSString *)substring;
- (void)removeSubstring:(NSString *)substring;
- (SCText *)cutTextInRange:(NSRange)range;
- (void)removeText:(SCStrings *)text;

Замена текста

Класс SCText декларирует следующие методы для замены текстовых блоков:

- (void)replaceTextInRange:(NSRange)range withText:(SCStrings *)text;
- (void)replaceTextInRange:(NSRange)range withCollection:(id<SCCollection>)collection;
- (void)replaceText:(SCStrings *)oldText withText:(SCStrings *)newText;

Перемещение и копирование текста

Класс SCText дополняет методы копирования и перемещения строк класса SCStrings собственными методами по манипулированию текстовыми блоками:

- (void)exchangeTextInRange:(NSRange)source withTextInRange:(NSRange)destination;
- (void)duplicateTextInRange:(NSRange)range;
- (void)duplicateStringsInRange:(NSRange)range;
- (void)copyTextInRange:(NSRange)range toIndex:(SCIndex)destination;
- (void)moveTextInRange:(NSRange)range toIndex:(SCIndex)destination;
- (void)forwardMoveTextInRange:(NSRange)range steps:(SCIndex)steps;
- (void)forwardMoveTextInRange:(NSRange)range;
- (void)backwardMoveTextInRange:(NSRange)range steps:(SCIndex)steps;
- (void)backwardMoveTextInRange:(NSRange)range;
- (void)moveToFirstPositionTextInRange:(NSRange)range;
- (void)moveToLastPositionTextInRange:(NSRange)range;

Доступ к тексту

Методы доступа к тексту являются важным дополнением к методам доступа к строкам, которые класс SCText унаследовал от класса SCStrings. На сегодняшний день к методам доступа к тексту относятся следующие методы:

- (SCText *)textInRange:(NSRange)range;

Поиск и выбор строк

Класс SCText дополняет механизмы поиска строк класса SCStrings собственными методами поиска текстовых блоков:

- (BOOL)containsText:(SCStrings *)text;
- (NSRange)rangeOfText:(SCStrings *)text;
- (NSRange)rangeOfCollection:(id<SCCollection>)collection;
- (SCIndex)indexOfText:(SCStrings *)text;
- (SCIndex)indexOfCollection:(id<SCCollection>)collection;
- (SCUInteger)countOfText:(SCStrings *)text;
- (SCUInteger)countOfCollection:(id<SCCollection>)collection;
- (SCArray *)indexesOfText:(SCStrings *)text;
- (SCArray *)indexesOfCollection:(id<SCCollection>)collection;
- (SCTextIndex *)textIndexOfSubstring:(NSString *)substring;
- (SCArray *)textIndexesOfSubstring:(NSString *)substring;

Обращаем внимание, что работа данных методов зависит от значения свойства caseInsensitive.

Отбор текстовых блоков по различным критериям в дополнение к уже имеющимся методам класса SCStrings в классе SCText осуществляют следующие методы:

- (SCText *)textWithSubstring:(NSString *)substring;
- (SCText *)textWithoutSubstring:(NSString *)substring;

Напоминаем, что поведение данных методов зависит от значения свойства caseInsensitive.


Текстовые файлы

Класс SCTextFile дополняет функциональность родительского класса SCText возвожностями по работе с файлами на диске. Прежде всего это операции загрузки текстов из файлов, запись текстов в файлы, а также операции по чтению и записи отдельных текстовых блоков. При этом класс SCTextFile сохраняет всю фунциональность списков строк и текстов.


Свойства экземпляров класса

Наиболее важными свойствами экземпляра класса SCTextFile являются следующие свойства:

@property (nonatomic, readonly, retain) NSString *path;
@property (nonatomic, readonly, assign) BOOL modified;

Создание текстовых файлов

Класс SCTextFile предоставляет ряд классовых методов для создания экземпляров класса на основании данных из последовательных файлов, словарей, потоков и объектов данных:

+ (instancetype)textFileWithCoder:(NSCoder *)coder;
+ (instancetype)textFileWithContentsOfSerializedFile:(NSString *)path;
+ (instancetype)textFileWithDataDictionary:(NSDictionary *)dictionary;
+ (instancetype)textFileWithDataDictionaryFromFile:(NSString *)path;
+ (instancetype)textFileWithStream:(SCStream *)stream;
+ (instancetype)textFileWithFileStream:(NSString *)path;
+ (instancetype)textFileWithData:(NSData *)data;
+ (instancetype)textFileWithContentsOfFile:(NSString *)path;
+ (instancetype)textFileWithContentsOfURL:(NSURL *)url;
+ (instancetype)textFileWithContentsOfURLString:(NSString *)urlString;

Для создания экземпляров класса SCTextFile декларирует следующие классовые методы:

+ (instancetype)textFileWithName:(NSString *)name;
+ (instancetype)textFileWithString:(NSString *)string;
+ (instancetype)textFileWithStrings:(SCStrings *)strings;
+ (instancetype)textFileWithCollection:(id<SCCollection>)collection;
+ (instancetype)textFileWithArray:(SCArray *)array;
+ (instancetype)textFileWithText:(SCText *)text;
+ (instancetype)textFileWithTextFile:(SCTextFile *)textFile;
+ (instancetype)textFileWithName:(NSString *)name stream:(SCStream *)stream;
+ (instancetype)textFileFromStream:(SCStream *)stream;
+ (instancetype)textFileWithName:(NSString *)name path:(NSString *)path;
+ (instancetype)textFileWithPath:(NSString *)path;
+ (instancetype)textFile;

Инициализация текстовых файлов

Класс SCTextFile дополняет классы-предки следующими методами инициализации экземпляров класса:

- (instancetype)initWithTextFile:(SCTextFile *)textFile;
- (instancetype)initWithName:(NSString *)name stream:(SCStream *)stream;
- (instancetype)initFromStream:(SCStream *)stream;
- (instancetype)initWithName:(NSString *)name path:(NSString *)path;
- (instancetype)initWithPath:(NSString *)path;

Копирование текстовых файлов

Копирование текстовых файлов осуществляется следующими методами класса SCTextFile:

- (void)setTextFile:(SCTextFile *)textFile;

Получение новых текстовых файлов

Класс SCTextFile реализует ряд методов для создания новых текстовых файлов с использованием строк из существующих текстовых файлов:

- (instancetype)textFileByAddingString:(NSString *)string;
- (instancetype)textFileByAddingCollection:(id<SCCollection>)collection;
- (instancetype)textFileByAddingStringsFromArray:(SCArray *)array;
- (instancetype)textFileByAddingArray:(SCArray *)array;
- (instancetype)textFileByAddingStrings:(SCStrings *)strings;
- (instancetype)textFileByAddingText:(SCText *)text;
- (instancetype)textFileByAddingTextFile:(SCTextFile *)textFile;
- (instancetype)textFileByAddingTextFileWithPath:(NSString *)path;

Преобразование текстовых файлов

Класс SCTextFile объявляет следующие свойства преобразования текстовых файлов в экземпляры других классов:

@property (nonatomic, readonly, assign) SCStrings *strings;
@property (nonatomic, readonly, assign) SCUniqueStrings *uniqueStrings;
@property (nonatomic, readonly, assign) SCText *text;

Чтение и запись текстовых файлов

Класс SCTextFile декларирует следующие методы для чтения текстовых файлов:

- (BOOL)readFromStream:(SCStream *)stream;
- (BOOL)readWithPath:(NSString *)path;
- (BOOL)read;
- (BOOL)reset;

Все методы возвращают значение YES при успешном выполнении операции чтения и NO при возникновении какой-либо ошибки.

Запись данных в файлы осуществляется следующими методами класса SCTextFile:

- (BOOL)writeTextToStream:(SCStream *)stream;
- (BOOL)writeWithPath:(NSString *)path;
- (BOOL)write;
- (BOOL)appendToFileWithPath:(NSString *)path;

Чтение и запись текстовых блоков

Для осуществления загрузки текстовых блоков класс SCTextFile декларирует следующие методы:

- (BOOL)addTextFromStream:(SCStream *)stream;
- (BOOL)addTextWithPath:(NSString *)path;
- (BOOL)insertTextFromStream:(SCStream *)stream atIndex:(SCIndex)index;
- (BOOL)insertTextWithPath:(NSString *)path atIndex:(SCIndex)index;

При рассмотрении данных методов мы будем использовать созданный нами текстовый файл /tmp/sample.txt:

String 10
String 11

Замену текстовых блоков на строки из файлов обеспечивают следующие методы класса SCTextFile:

- (BOOL)replaceTextInRange:(NSRange)range withTextFromStream:(SCStream *)stream;
- (BOOL)replaceTextInRange:(NSRange)range withTextWithPath:(NSString *)path;
- (BOOL)replaceText:(SCStrings *)text withTextFromStream:(SCStream *)stream;
- (BOOL)replaceText:(SCStrings *)text withTextWithPath:(NSString *)path;

Запись текстовых блоков в классе SCTextFile обеспечивают следующие методы:

- (BOOL)writeTextInRange:(NSRange)range toStream:(SCStream *)stream;
- (BOOL)writeTextInRange:(NSRange)range withPath:(NSString *)path;
- (BOOL)appendTextInRange:(NSRange)range toFileWithPath:(NSString *)path;
- (SCText *)cutTextInRange:(NSRange)range toStream:(SCStream *)stream;
- (SCText *)cutTextInRange:(NSRange)range withPath:(NSString *)path;
- (SCText *)cutAndAppendTextInRange:(NSRange)range toFileWithPath:(NSString *)path;

Кроме вышеперечисленных методов класс SCTextFile объявляет методы, которые записывают в файлы строки, отобранные по определенным критериям:

- (BOOL)writeTextWithSubstring:(NSString *)substring toStream:(SCStream *)stream;
- (BOOL)writeTextWithSubstring:(NSString *)substring withPath:(NSString *)path;
- (BOOL)writeTextWithoutSubstring:(NSString *)substring toStream:(SCStream *)stream;
- (BOOL)writeTextWithoutSubstring:(NSString *)substring withPath:(NSString *)path;

Обработка ошибок

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

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


Алгоритм обработки ошибок

Основной алгоритм обаботки обнаруженных ошибок реализован в классе SCStrings. Его потомки применяют данный алгоритм для обработки собственных ошибок (ошибок, характерных только для данного дочернего класса).

При обнаружении ошибок экземпляр класса SCStrings поступает следующим образом:

  1. Если экземпляру класса назначен объект делегирования, то выполняется вызов его метода text:didDetectException:, которому передаются указатель на обнаруживший ошибку экземпляр класса и указатель на данные об ошибке в виде экземпляра класса исключительной ситуации SCTextException.
  2. Если метод объекта делегирования возвращает значение YES, экземпляр класса игнорирует данную ошибку с остановкой работы метода, во время выполнения которого была зафиксирована ошибочная ситуация.
  3. В том случае, если метод объекта делегирования возвращает значение NO или объект делегирования не был назначен, осуществляется генерация исключительной ситуации SCTextException, благодаря чему функция обработки данной ошибки передается на более высокий уровень программного кода.

Ошибки списков строк

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

SCTextErrorSource = -20061, // Исходный объект не существует
SCTextErrorReadOnly = -20063, // Нарушение режима только для чтения
SCTextErrorEmptyString = -20064, // Добавление нулевой строки
SCTextErrorUnsupported = -20066, // Обнаружен неподдерживаемый класс
SCTextErrorSorter = -20070, // Некорректный сортировщик строк
SCTextErrorIndex = -20072, // Недопустимый индекс
SCTextErrorIndexSet = -20074, // Некорректный список индексов строк
SCTextErrorIndexesCount = -20075, // Несоответствие количества индексов и строк

Ошибки списков уникальных строк

Класс SCUniqueStrings дополняет родительский класс SCStrings следующими исключительными ситуациями:

SCTextErrorDuplicated = -20069, // Нарушение уникальности строк

Ошибки текстов

Класс SCText также дополняет унаследованные исключительные ситуации собственными, связанными с функциональностью самого класса:

SCTextErrorRange = -20073, // Недопустимый диапазон строк
SCTextErrorIntersected = -20076, // Пересекающиеся диапазоны строк

Ошибки текстовых файлов

Как и другие потомки класса SCStrings, класс SCTextFile добавляет свои собственные исключительные ситуации, связанные с различными ошибками при выполнении операций ввода-вывода. Обращаем внимание, что в ряде случаев (в зависимости от режимов работы используемых потоков) вместо генерации исключительной ситуации SCTextException возможна генерация исключительных ситуаций SCStreamException и SCSystemException.

SCTextErrorInputStream = -20062, // Некорректный входной поток
SCTextErrorClosedStream = -20065, // Работа с закрытым потоком
SCTextErrorRead = -20067, // Ошибка чтения данных из потока
SCTextErrorEmptyPath = -20068, // Пустой путь к текстовому файлу
SCTextErrorOutputStream = -20071, // Некорректный выходной поток
SCTextErrorWrite = -20077, // Ошибка записи данных в поток

Протокол делегирования SCTextDelegate

Протокол делегирования SCTextDelegate декларирует методы, которые можно разделить на ряд функциональных групп:

Подробные описания данных методов приводятся в описании протокола SCTextDelegate и в соответствующих разделах данного руководства.


Текстовые индексы

Текстовый индекс - экземпляр класса SCTextIndex, который содержит в себе данные о позиции внутри текста, состоящие из номера (индекса) строки и номера (индекса) символа в строке. Является вспомогательным классом для текстовых классов и самостоятельно не используется.

Для доступа к хранящимся в экземпляре класса индексам объявлены следующие свойства и методы:

@property (nonatomic, readwrite, assign) SCIndex line;
@property (nonatomic, readwrite, assign) SCIndex character;
- (void)setLine:(SCULong)line;
- (void)setCharacter:(SCULong)character;

Создание экземпляров класса SCTextIndex выполняется с помощью классовых методов, а также специальной функции:

+ (instancetype)textIndexWithLine:(SCULong)line character:(SCULong)character;
+ (instancetype)textIndexWithTextIndex:(SCTextIndex *)textIndex;
+ (instancetype)textIndex;

Взаимодействие с объектами данных

Стандартные классы данных (NSData и NSMutableData) обеспечивают хранение нетипизированных данных в виде последовательности байтов. Ряд стандартных классов имеет методы для создания экземпляров классов из объектов данных и для сохранения экземпляров классов в объектах данных. Библиотека дополняет подобными методами как собственные классы, так и стандартные классы, таких методов не имеющие.

Поскольку экземпляры класса NSData имеют методы для загрузки и сохранения данных в файлах и с использованием URL, к методам взаимодействия с объектами данных библиотека добавляет и методы работы с файлами и URL.

Данный раздел документации описывает данные методы и приводит примеры по их использованию:


Методы взаимодействия с объектами данных

Протокол SCDating определяет следующие для взаимодействия экземпляров классов с объектами данных:

- (instancetype)initWithData:(NSData *)data;
- (instancetype)initWithDataWrapper:(SCData *)data;
- (void)writeToData:(NSMutableData *)data;
- (NSData *)data;

Методы взаимодействия с файлами

Для работы с файлами протокол SCDating определяет следующие методы:

- (instancetype)initWithContentsOfURL:(NSURL *)url;
- (BOOL)writeToFile:(NSString *)path;

Методы взаимодействия с URL

Objective-C определяет специальный класс NSURL для работы с URL. Однако в ряде случаев удобнее задавать URL не через экземпляры данного класса, а напрямую через текстовые строки. Поэтому протокол SCDating определяет методы для работы с URL, которые в качестве аргументов принимают как экземпляры класса NSURL, так и строки:

- (instancetype)initWithContentsOfURL:(NSURL *)url;
- (instancetype)initWithContentsOfURLString:(NSString *)urlString;
- (BOOL)writeToURL:(NSURL *)url;
- (BOOL)writeToURLString:(NSString *)urlString;

Расширения класса NSString

Стандартный класс NSString обеспечивает программистов большим кругом функциональных возможностей. Тем не менее, всегда находятся те или иные нужды и предложения, которыми хочется дополнить базовую функциональность данного стандартного класса.

Благодаря возможностям языке Objective-C это можно сделать без необходимости создавать дочерние классы, что потребовало бы в программном коде использовать экземпляры этих дочерних классов. Благодаря категориям мы можем расширить функциональность существующего класса и вызывать новые возможности при использовании экземпляров самого класса, а не его потомков.

Данный раздел руководства программирования описывает расширения, обеспечиваемые категорией NSString(SCString), в том числе и добавление поддержки стандартных возможностей нашей библиотеки (потоки, словари, коллекции и так далее). Рассматривать добавленные нами возможности мы будем с учетом их группировки по следующим группам:


Создание строк

Для создания строк из последовательных файлов, словарей и потоков используются следующие методы категории NSString(SCString):

+ (instancetype)stringWithCoder:(NSCoder *)coder;
+ (instancetype)stringWithContentsOfSerializedFile:(NSString *)path;
+ (instancetype)stringWithDataDictionary:(NSDictionary *)dictionary;
+ (instancetype)stringWithDataDictionaryFromFile:(NSString *)path;
+ (instancetype)stringWithStream:(SCStream *)stream;
+ (instancetype)stringWithFileStream:(NSString *)path;

Поддержка объектов данных обеспечивается следующими методами категории:

+ (instancetype)stringWithData:(NSData *)data;
+ (instancetype)stringWithContentsOfFile:(NSString *)path;
+ (instancetype)stringWithContentsOfURL:(NSURL *)url;
+ (instancetype)stringWithContentsOfURLString:(NSString *)urlString;

Категория NSString(SCString) дополняет класс NSString следующими классовыми методами создания текстовых строк:

+ (instancetype)stringWithIndexSet:(NSIndexSet *)indexSet;
+ (instancetype)stringWithCharacter:(unichar)character;
+ (instancetype)stringWithCharacter:(unichar)character length:(SCIndex)length;
+ (instancetype)stringWithLength:(SCUInteger)length;
+ (instancetype)stringWithPointer:(void *)pointer;
+ (instancetype)stringWithID:(id)object;

Инициализация строк

Кроме классовых методов создания экземпляров класса NSString категория NSString(SCString) декларирует дополнительные методы инициализации строк:

- (instancetype)initWithIndexSet:(NSIndexSet *)indexSet;
- (instancetype)initWithCharacter:(unichar)character;
- (instancetype)initWithCharacter:(unichar)character length:(SCIndex)length;
- (instancetype)initWithLength:(SCUInteger)length;
- (instancetype)initWithPointer:(void *)pointer;
- (instancetype)initWithID:(id)object;

Разделение и замена строк и подстрок

Категория NSString(SCString) дополняет стандартный класс NSString большим диапазоном свойств и методов разделения строк на части и замены строк и подстрок. Для удобства их описания глава разделяется на ряд параграфов в соответствии с назначением свойств и методов:


Отбрасывание частей строк

@property (nonatomic, readonly, assign) NSString *trimmedString;
- (NSString *)ltrim;
- (NSString *)rtrim;
- (NSString *)trim;
- (NSString *)stringWithLeftCharacters:(SCIndex)characters;
- (NSString *)stringWithRightCharacters:(SCIndex)characters;
- (NSString *)skipLeftPart:(SCIndex)characters;
- (NSString *)skipRightPart:(SCIndex)characters;

Поиск подстрок

- (BOOL)isCorrectRange:(NSRange)range;
- (BOOL)existsSubstring:(NSString *)substring caseInsensitive:(BOOL)caseInsensitive;
- (BOOL)existsSubstring:(NSString *)substring;
- (SCIndex)countOfSubstring:(NSString *)substring caseInsensitive:(BOOL)caseInsensitive;
- (SCIndex)countOfSubstring:(NSString *)substring;
- (SCIndex)indexOfSubstring:(NSString *)substring caseInsensitive:(BOOL)caseInsensitive;
- (SCIndex)indexOfSubstring:(NSString *)substring;
- (NSArray *)indexesOfSubstring:(NSString *)substring caseInsensitive:(BOOL)caseInsensitive;
- (NSArray *)indexesOfSubstring:(NSString *)substring;

Удаление подстрок

- (NSString *)stringWithDeletedSubstring:(NSString *)substring caseInsensitive:(BOOL)caseInsensitive;
- (NSString *)stringWithDeletedSubstring:(NSString *)substring;
- (NSString *)stringWithDeletedSubstringToIndex:(SCIndex)index;
- (NSString *)stringWithDeletedSubstringToRange:(NSRange)range;
- (NSString *)stringWithDeletedSubstringFromIndex:(SCIndex)index;
- (NSString *)stringWithDeletedSubstringWithRange:(NSRange)range;

Замена подстрок

- (NSString *)stringWithReplacedSubstringToIndex:(SCUInteger)index withString:(NSString *)string;
- (NSString *)stringWithReplacedSubstringFromIndex:(SCUInteger)index withString:(NSString *)string;
- (NSString *)stringWithReplacedSubstringWithRange:(NSRange)range withString:(NSString *)string;
- (NSString *)stringWithReplacedSubstring:(NSString *)substring
withString:(NSString *)string
caseInsensitive:(BOOL)caseInsensitive;
- (NSString *)stringWithReplacedSubstring:(NSString *)substring withString:(NSString *)string;

Вставка подстрок

- (NSString *)stringWithInsertedString:(NSString *)string;
- (NSString *)stringWithInsertedString:(NSString *)string index:(SCUInteger)index;

Работа со словами в составе строк

Работа с отдельными словами текстовых строк осуществляется следующими свойствами и методами категории NSString(SCString):

@property (nonatomic, readonly, assign) NSString *normalizedString;
@property (nonatomic, readonly, assign) SCIndex wordsCount;
@property (nonatomic, readonly, assign) NSString *firstWord;
@property (nonatomic, readonly, assign) NSString *lastWord;
@property (nonatomic, readonly, assign) NSString *endOfString;
- (NSString *)word:(SCIndex)word;

Сравнение строк

Существующие в классе NSString методы сравнения экземпляров класса дополняются следующими методами категории NSString(SCString):

- (BOOL)isEqualToStrings:(NSString *)string, ...;

Расширение строк

Категория NSString(SCString) декларирует следующие методы расширения строк:

- (NSString *)leftExpandedStringToLength:(SCIndex)length character:(unichar)character;
- (NSString *)leftExpandedStringToLength:(SCIndex)length;
- (NSString *)leftZeroExpandedStringToLength:(SCIndex)length;
- (NSString *)rightExpandedStringToLength:(SCIndex)length character:(unichar)character;
- (NSString *)rightExpandedStringToLength:(SCIndex)length;

Кроме вышеописанных методов категория NSString(SCString) декларирует классовые методы, создающие строки с расширением до указанной длины соответствующими символами на основании заданных исходных строк:

+ (instancetype)stringWithLeftExpandedString:(NSString *)string length:(SCIndex)length character:(unichar)character;
+ (instancetype)stringWithLeftExpandedString:(NSString *)string length:(SCIndex)length;
+ (instancetype)stringWithLeftZeroExpandedString:(NSString *)string length:(SCIndex)length;
+ (instancetype)stringWithRightExpandedString:(NSString *)string length:(SCIndex)length character:(unichar)character;
+ (instancetype)stringWithRightExpandedString:(NSString *)string length:(SCIndex)length;

Аналогичные функции выполняют методы инициализации строк:

- (instancetype)initWithLeftExpandedString:(NSString *)string length:(SCIndex)length character:(unichar)character;
- (instancetype)initWithLeftExpandedString:(NSString *)string length:(SCIndex)length;
- (instancetype)initWithLeftZeroExpandedString:(NSString *)string length:(SCIndex)length;
- (instancetype)initWithRightExpandedString:(NSString *)string length:(SCIndex)length character:(unichar)character;
- (instancetype)initWithRightExpandedString:(NSString *)string length:(SCIndex)length;

Добавление разделителей групп символов

Методы, возвращающие разделенные на группы символов строки, декларированы в категории NSString(SCString) следующим образом:

- (NSString *)stringWithSeparator:(NSString *)separator left:(SCIndex)left;
- (NSString *)stringWithSpacesLeft:(SCIndex)left;
- (NSString *)stringWithSeparator:(NSString *)separator right:(SCIndex)right;
- (NSString *)stringWithSpacesRight:(SCIndex)right;

Кроме методов, возвращающих строки с добавленными разделителями, категория NSString(SCString) декларирует классовые методы и методы инициализации новых строк с добавленными разделителями на основе существующих исходных строк:

+ (instancetype)stringWithString:(NSString *)string separator:(NSString *)separator left:(SCIndex)left;
+ (instancetype)stringWithString:(NSString *)string spacesLeft:(SCIndex)left;
+ (instancetype)stringWithString:(NSString *)string separator:(NSString *)separator right:(SCIndex)right;
+ (instancetype)stringWithString:(NSString *)string spacesRight:(SCIndex)right;
- (instancetype)initWithString:(NSString *)string separator:(NSString *)separator left:(SCIndex)left;
- (instancetype)initWithString:(NSString *)string spacesLeft:(SCIndex)left;
- (instancetype)initWithString:(NSString *)string separator:(NSString *)separator right:(SCIndex)right;
- (instancetype)initWithString:(NSString *)string spacesRight:(SCIndex)right;

Работа с текстовыми представлениями различных типов данных

Данная глава описывает свойства и методы категории NSString(SCString), обеспечивающие взаимодействие между числовыми данными и их текстовыми представлениями в виде строк:


Определение наличия в строках чисел

Категория NSString(SCString) объявляет ряд свойств, позволяющих определить, является ли та или иная строка символьным представлением числа в различных форматах:

@property (nonatomic, readonly, assign) BOOL isBinaryString;
@property (nonatomic, readonly, assign) BOOL isOctalString;
@property (nonatomic, readonly, assign) BOOL isDecimalString;
@property (nonatomic, readonly, assign) BOOL isHexadecimalString;
@property (nonatomic, readonly, assign) BOOL isBooleanString;
@property (nonatomic, readonly, assign) BOOL isFloatString;
@property (nonatomic, readonly, assign) BOOL isDoubleString;

Преобразование строк в числовой формат

Категория NSString(SCString) объявляет ряд свойств для преобразования различных текстовых представлений чисел в целые и логические значения:

@property (nonatomic, readonly, assign) SCULong binaryValue;
@property (nonatomic, readonly, assign) SCULong octalValue;
@property (nonatomic, readonly, assign) SCULong decimalValue;
@property (nonatomic, readonly, assign) SCULong hexadecimalValue;
@property (nonatomic, readonly, assign) BOOL booleanValue;

Создание символьных представлений чисел

Категория NSString(SCString) объявляет ряд классовых методов, возвращающих созданные текстовые представления целых чисел и логических значений:

+ (instancetype)stringWithBinaryInteger:(SCULong)integer capacity:(SCCapacity)capacity;
+ (instancetype)stringWithBinaryInteger:(SCULong)integer;
+ (instancetype)stringWithOctalInteger:(SCULong)integer;
+ (instancetype)stringWithDecimalInteger:(SCLong)integer separators:(BOOL)separators;
+ (instancetype)stringWithDecimalInteger:(SCLong)integer;
+ (instancetype)stringWithInteger:(SCLong)integer;
+ (instancetype)stringWithHexadecimalInteger:(SCULong)integer capacity:(SCCapacity)capacity;
+ (instancetype)stringWithHexadecimalInteger:(SCULong)integer;
+ (instancetype)stringWithBool:(BOOL)boolean;
+ (instancetype)stringWithFloat:(SCFloat)value;
+ (instancetype)stringWithDouble:(SCDouble)value;

Инициализация символьных представлений чисел

Категория NSString(SCString) декларирует ряд методов для инициализации строк как различных представлений чисел и логических значений:

- (instancetype)initWithBinaryInteger:(SCULong)integer capacity:(SCCapacity)capacity;
- (instancetype)initWithBinaryInteger:(SCULong)integer;
- (instancetype)initWithOctalInteger:(SCULong)integer;
- (instancetype)initWithDecimalInteger:(SCLong)integer separators:(BOOL)separators;
- (instancetype)initWithDecimalInteger:(SCLong)integer;
- (instancetype)initWithInteger:(SCLong)integer;
- (instancetype)initWithHexadecimalInteger:(SCULong)integer capacity:(SCCapacity)capacity;
- (instancetype)initWithHexadecimalInteger:(SCULong)integer;
- (instancetype)initWithBool:(BOOL)boolean;
- (instancetype)initWithFloat:(SCFloat)value;
- (instancetype)initWithDouble:(SCDouble)value;

Реверсирование строк

Реверсирование строк осуществляется следующими методами категории NSString(SCString):

@property (nonatomic, readonly, assign) NSString *reversedString;
+ (instancetype)stringWithReversedString:(NSString *)string;
- (instancetype)initWithReversedString:(NSString *)string;

Другие методы

Кроме вышеперечисленных свойств и методов категория NSString(SCString) декларирует следующие свойства, которые нельзя отнести к какой-либо конкретной группе:

@property (nonatomic, readonly, assign) BOOL empty;
@property (nonatomic, readonly, assign) NSString *stringWithUpperFirstLetter;

Расширения стандартных классов

В предыдущем разделе была описана категория NSString(SCString), расширяющая функциональность стандартного класса NSString. Кроме этого класса многие другие стандартные классы получили в нашей библиотеке дополнительную функциональность. В данном разделе мы опишем расширения следующих классов:


Расширение класса NSObject

Базовый стандартный класс NSObject реализует стандартные для всех классов возможности. Именно поэтому нами была создана категория NSObject(SCObject), через которую мы добавляем поддержку механизмов нашей библиотеки сразу во все классы, прежде всего поддержку протоколов SCCoding, SCDictionaring, SCStreaming, SCCollectioning и SCDating.

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


Поддержка последовательных файлов

Для обеспечения поддержки последовательных файлов путем реализации протокола SCCoding категория NSObject(SCObject) декларирует следующие методы:

- (instancetype)initWithCoder:(NSCoder *)coder;
- (instancetype)initWithContentsOfSerializedFile:(NSString *)path;
- (void)encodeWithCoder:(NSCoder *)coder;
- (BOOL)writeContentsToSerializedFile:(NSString *)path;

Поддержка словарей

В целях обеспечения поддержки словарей через реализацию методов протокола SCDictionaring категория NSObject(SCObject) объявляет следующие методы:

- (instancetype)initWithDataDictionary:(NSDictionary *)dictionary;
- (instancetype)initWithDataDictionaryFromFile:(NSString *)path;
- (void)writeToDataDictionary:(NSMutableDictionary *)dictionary;
- (void)writeToDataDictionaryFile:(NSString *)path atomically:(BOOL)atomically;
- (void)writeToDataDictionaryFile:(NSString *)path;
- (NSDictionary *)dataDictionary;

Поддержка потоков

Реализуя следующие методы протокола SCStreaming категория NSObject(SCObject) обеспечивает поддержку потоков:

- (instancetype)initWithStream:(SCStream *)stream;
- (instancetype)initWithFileStream:(NSString *)path;
- (void)writeToStream:(SCStream *)stream;
- (void)writeToFileStream:(NSString *)path;
- (void)appendToFileStream:(NSString *)path;

Поддержка коллекций

Чтобы обеспечить поддержку коллекций категория NSObject(SCObject) реализует следующие методы протокола SCCollectioning:

- (id)copyObject;
- (SCComparisonResult)compareWithObject:(id<SCCollectioning>)object;

Взаимодействие с объектами данных

Взаимодействие с объектами данных, а также с файлами и URL обеспечивается следующими методами категории NSObject(SCObject):

- (instancetype)initWithData:(NSData *)data;
- (instancetype)initWithContentsOfFile:(NSString *)path;
- (instancetype)initWithContentsOfURL:(NSURL *)url;
- (instancetype)initWithContentsOfURLString:(NSString *)urlString;
- (void)writeToData:(NSMutableData *)data;
- (BOOL)writeToFile:(NSString *)path;
- (BOOL)writeToURL:(NSURL *)url;
- (BOOL)writeToURLString:(NSString *)urlString;
- (NSData *)data;

Расширение класса NSNumber

Класс числовых объектов NSNumber обеспечивает в стандартной библиотеке возможности по работе с целыми числами, логическими значениями и числами с плавающей точкой. Большое значение данного класса для всего языка Objective C обусловило необходимость его расширения как для поддержки стандартных механизмов библиотеки, так и для внесения в класс дополнительной функциональности.


Создание числовых объектов

Категория NSNumber(SCNumber) реализует ряд классовых методов для создания числовых объектов на основании данных из последовательных файлов, словарей, потоков и объектов данных:

+ (instancetype)numberWithCoder:(NSCoder *)coder;
+ (instancetype)numberWithContentsOfSerializedFile:(NSString *)path;
+ (instancetype)numberWithDataDictionary:(NSDictionary *)dictionary;
+ (instancetype)numberWithDataDictionaryFromFile:(NSString *)path;
+ (instancetype)numberWithStream:(SCStream *)stream;
+ (instancetype)numberWithFileStream:(NSString *)path;
+ (instancetype)numberWithData:(NSData *)data;
+ (instancetype)numberWithContentsOfFile:(NSString *)path;
+ (instancetype)numberWithContentsOfURL:(NSURL *)url;
+ (instancetype)numberWithContentsOfURLString:(NSString *)urlString;

Категория NSNumber(SCNumber) декларирует ряд классовых методов для создания экземпляров класса на основании данных других типов:

+ (instancetype)numberWithNumber:(NSNumber *)number;
+ (instancetype)numberWithByte:(SCByte)byte;
+ (instancetype)numberWithUnsignedByte:(SCUByte)byte;
+ (instancetype)numberWithUnichar:(unichar)chr;

Создание числовых объектов на основании их текстового представления того или иного формата осуществляется рядом классовым методов категории NSNumber(SCNumber):

+ (instancetype)numberWithBinaryString:(NSString *)string;
+ (instancetype)numberWithOctalString:(NSString *)string;
+ (instancetype)numberWithDecimalString:(NSString *)string;
+ (instancetype)numberWithHexadecimalString:(NSString *)string;
+ (instancetype)numberWithString:(NSString *)string;
+ (instancetype)numberWithBoolString:(NSString *)string;
+ (instancetype)numberWithFloatString:(NSString *)string;
+ (instancetype)numberWithDoubleString:(NSString *)string;

Инициализация числовых объектов

Категория NSNumber(SCNumber) определяет ряд методов инициализации экземпляров класса с использованием существующих данных каких-либо типов:

- (instancetype)initWithNumber:(NSNumber *)number;
- (instancetype)initWithByte:(SCByte)byte;
- (instancetype)initWithUnsignedByte:(SCUByte)byte;
- (instancetype)initWithUnichar:(unichar)chr;

Категория NSNumber(SCNumber) декларирует методы для инициализации экземпляров класса с использованием различных видов текстовых представлений чисел:

- (instancetype)initWithBinaryString:(NSString *)string;
- (instancetype)initWithOctalString:(NSString *)string;
- (instancetype)initWithDecimalString:(NSString *)string;
- (instancetype)initWithHexadecimalString:(NSString *)string;
- (instancetype)initWithString:(NSString *)string;
- (instancetype)initWithBoolString:(NSString *)string;
- (instancetype)initWithFloatString:(NSString *)string;
- (instancetype)initWithDoubleString:(NSString *)string;

Свойства экземпляров класса

Категория NSNumber(SCNumber) объявляет следующие свойства:

@property (nonatomic, readonly, assign) SCByte byteValue;
@property (nonatomic, readonly, assign) SCUByte unsignedByteValue;
@property (nonatomic, readonly, assign) unichar unicharValue;

Кроме вышеперечисленных свойств в категории NSNumber(SCNumber) объявлены свойства для получения различных текстовых представлений числовых объектов:

@property (nonatomic, readonly, assign) NSString *binaryString;
@property (nonatomic, readonly, assign) NSString *octalString;
@property (nonatomic, readonly, assign) NSString *decimalString;
@property (nonatomic, readonly, assign) NSString *string;
@property (nonatomic, readonly, assign) NSString *hexadecimalString;
@property (nonatomic, readonly, assign) NSString *boolString;
@property (nonatomic, readonly, assign) NSString *floatString;
@property (nonatomic, readonly, assign) NSString *doubleString;

Определение типов числовых объектов

Числовой объект NSNumber может содержать данные различного типа, который определяется при создании экземпляра класса. Для получения информации о типе числового объекта категория NSNumber(SCNumber) используется свойство type, объявленное в категории следующим образом:

@property (nonatomic, readonly, assign) SCStandardType type;

Свойство возвращает идентификатор типа числового объекта. Подробнее доступные идентификаторы описаны в разделе стандартные типы данных данного руководства.

NSNumber *number = [NSNumber numberWithShort:1909];
if ( number.type == SCTypeShort) NSLog( @"number is signed short");
2016-09-14 17:33:22.302 libtest[5377:337635] number is signed short

Сравнение экземпляров класса

Для выполнения операций сравнения числовых объектов с различными типами данных, категория NSNumber(SCNumber) определяет ряд методов, которые возвращают значение YES если проверяемый числовой объект соответствует указанному в качестве аргумента соответствующего метода значению:

- (BOOL)isEqualToByte:(SCByte)value;
- (BOOL)isEqualToUnsignedByte:(SCUByte)value;
- (BOOL)isEqualToShort:(SCShort)value;
- (BOOL)isEqualToUnsignedShort:(SCUShort)value;
- (BOOL)isEqualToInteger:(SCInteger)value;
- (BOOL)isEqualToUnsignedInteger:(SCUInteger)value;
- (BOOL)isEqualToLongLong:(SCLong)value;
- (BOOL)isEqualToUnsignedLongLong:(SCULong)value;
- (BOOL)isEqualToChar:(char)value;
- (BOOL)isEqualToUnichar:(unichar)value;
- (BOOL)isEqualToBool:(BOOL)value;
- (BOOL)isEqualToFloat:(SCFloat)value;
- (BOOL)isEqualToDouble:(SCDouble)value;

Для выполнения сравнения числовых объектов с текстовыми представлениями данных (как представленных в виде экземпляров класса NSString, так и в виде классических строк) категория NSNumber(SCNumber) декларирует следующий ряд методов:

- (BOOL)isEqualToBinaryString:(NSString *)string;
- (BOOL)isEqualToOctalString:(NSString *)string;
- (BOOL)isEqualToDecimalString:(NSString *)string;
- (BOOL)isEqualToHexadecimalString:(NSString *)string;
- (BOOL)isEqualToString:(NSString *)string;
- (BOOL)isEqualToBoolString:(NSString *)string;
- (BOOL)isEqualToFloatString:(NSString *)string;
- (BOOL)isEqualToDoubleString:(NSString *)string;

Обработка ошибок

При работе с последовательными файлами, словарями, потоками и коллекциями мы можем столкнуться с ситуацией, когда вместо числового объекта будет обнаружен экземпляр другого класса. Для индикации данной ситуации нами была создана исключительная ситуация SCNumberException, реализующая на данный момент единственную ошибку SCL-20011.


Расширение класса NSNull

Категория NSNull(SCNull) не добавляет к классу NSNull никакой новой функциональности, за исключением классовых методов создания экземпляров класса на основании данных из последовательных файлов, словарей, потоков и объектов данных:

+ (instancetype)nullWithCoder:(NSCoder *)coder;
+ (instancetype)nullWithContentsOfSerializedFile:(NSString *)path;
+ (instancetype)nullWithDataDictionary:(NSDictionary *)dictionary;
+ (instancetype)nullWithDataDictionaryFromFile:(NSString *)path;
+ (instancetype)nullWithStream:(SCStream *)stream;
+ (instancetype)nullWithFileStream:(NSString *)path;
+ (instancetype)nullWithData:(NSData *)data;
+ (instancetype)nullWithContentsOfFile:(NSString *)path;
+ (instancetype)nullWithContentsOfURL:(NSURL *)url;
+ (instancetype)nullWithContentsOfURLString:(NSString *)urlString;

Расширение класса NSDate

Как и категория NSNull(SCNull), категория NSDate(SCDate) расширяет функциональность класса NSDate методами для создания экземпляров класса на основании данных из последовательных файлов, словарей, потоков и объектов данных:

+ (instancetype)dateWithCoder:(NSCoder *)coder;
+ (instancetype)dateWithContentsOfSerializedFile:(NSString *)path;
+ (instancetype)dateWithDataDictionary:(NSDictionary *)dictionary;
+ (instancetype)dateWithDataDictionaryFromFile:(NSString *)path;
+ (instancetype)dateWithStream:(SCStream *)stream;
+ (instancetype)dateWithFileStream:(NSString *)path;
+ (instancetype)dateWithData:(NSData *)data;
+ (instancetype)dateWithContentsOfFile:(NSString *)path;
+ (instancetype)dateWithContentsOfURL:(NSURL *)url;
+ (instancetype)dateWithContentsOfURLString:(NSString *)urlString;

Расширение класса NSArray

Категория NSArray(SCArray) добавляет в стандартный класс NSArray функциональность таких протоколов библиотеки, как SCCollection и SCIndexedCollection, обеспечивая совместимость со многими механизмами библиотеки:


Создание массивов

Категория NSArray(SCArray) декларирует следующие классовые методы для создания массивов на основе данных из последовательных файлов, словарей, потоков и объектов данных:

+ (instancetype)arrayWithCoder:(NSCoder *)coder;
+ (instancetype)arrayWithContentsOfSerializedFile:(NSString *)path;
+ (instancetype)arrayWithDataDictionary:(NSDictionary *)dictionary;
+ (instancetype)arrayWithDataDictionaryFromFile:(NSString *)path;
+ (instancetype)arrayWithStream:(SCStream *)stream;
+ (instancetype)arrayWithFileStream:(NSString *)path;
+ (instancetype)arrayWithData:(NSData *)data;
+ (instancetype)arrayWithContentsOfURLString:(NSString *)urlString;

Категория NSArray(SCArray) добавляет в класс NSArray следующие методы создания массивов:

+ (instancetype)arrayWithCollection:(id<SCCollection>)collection;

Инициализация массивов

Категория NSArray(SCArray) объявляет следующие дополнительные методы инициализации массивов:

- (instancetype)initWithCollection:(id<SCCollection>)collection;

Реализация протокола SCCollection

Наиболее востребованными свойствами протокола SCCollection в классе NSArray являются следующие свойства категории NSArray(SCArray):

@property (nonatomic, readonly, retain) NSString *name;
@property (nonatomic, readonly, assign) BOOL empty;
@property (nonatomic, readonly, assign) BOOL readOnly;
@property (nonatomic, readonly, retain) id<SCCollectionDelegate> delegate;

Также для реализации протокола SCCollection категория NSArray(SCArray) реализует свойства, позволяющие определить тип коллекции:

@property (nonatomic, readonly, assign) SCCollectionType collectionType;
@property (nonatomic, readonly, assign) BOOL isCollection;
@property (nonatomic, readonly, assign) BOOL isLibraryCollection;
@property (nonatomic, readonly, assign) BOOL isFoundationCollection;
@property (nonatomic, readonly, assign) BOOL isArray;
@property (nonatomic, readonly, assign) BOOL isLibraryArray;
@property (nonatomic, readonly, assign) BOOL isFoundationArray;
@property (nonatomic, readonly, assign) BOOL isSet;
@property (nonatomic, readonly, assign) BOOL isLibrarySet;
@property (nonatomic, readonly, assign) BOOL isFoundationSet;
@property (nonatomic, readonly, assign) BOOL isOrderedSet;
@property (nonatomic, readonly, assign) BOOL isLibraryOrderedSet;
@property (nonatomic, readonly, assign) BOOL isFoundationOrderedSet;
@property (nonatomic, readonly, assign) BOOL isDictionary;
@property (nonatomic, readonly, assign) BOOL isLibraryDictionary;
@property (nonatomic, readonly, assign) BOOL isFoundationDictionary;
@property (nonatomic, readonly, assign) BOOL isStack;
@property (nonatomic, readonly, assign) BOOL isQueue;
@property (nonatomic, readonly, assign) BOOL isList;
@property (nonatomic, readonly, assign) BOOL isSortable;

Свойство collectionType экземпляров классов NSArray и NSMutableArray всегда возвращает значение SCCollectionFoundationArray.

Для экземпляров класса NSArray и его потомка NSMutableArray значение YES возвращают свойства:

Остальные свойства из этого списка возвращают значение NO.


Поиск объектов массивов

Категория NSArray(SCArray) реализует следующие свойства и методы поиска объектов из протокола SCCollection:

@property (nonatomic, readonly, assign) SCIndex indexOfLastObject;
- (BOOL)containsObjects:(id<SCCollectioning>)object, ...;
- (BOOL)containsCollection:(id<SCCollection>)collection;
- (BOOL)containsAnyObject:(id<SCCollectioning>)object, ...;
- (BOOL)containsAnyObjectFromCollection:(id<SCCollection>)collection;

Преобразование массивов

В соответствии с протоколом SCCollection категория NSArray(SCArray) реализует свойства преобразования массивов типа NSArray в другие виды поддерживаемых библиотекой коллекций:

@property (nonatomic, readonly, assign) SCArray *array;
@property (nonatomic, readonly, assign) SCSet *set;
@property (nonatomic, readonly, assign) SCOrderedSet *orderedSet;
@property (nonatomic, readonly, assign) SCDictionary *dictionary;
@property (nonatomic, readonly, assign) SCStack *stack;
@property (nonatomic, readonly, assign) SCQueue *queue;
@property (nonatomic, readonly, assign) SCUnidirectionalList *unidirectionalList;
@property (nonatomic, readonly, assign) SCBidirectionalList *bidirectionalList;
@property (nonatomic, readonly, assign) NSArray *foundationArray;
@property (nonatomic, readonly, assign) NSSet *foundationSet;
@property (nonatomic, readonly, assign) NSOrderedSet *foundationOrderedSet;
@property (nonatomic, readonly, assign) NSDictionary *foundationDictionary;
@property (nonatomic, readonly, assign) NSArray *reversedArray;

Сортировка массивов

Согласно протоколу SCCollection категория NSArray(SCArray) реализует следующие свойства и методы сортировки содержимого массива:

@property (nonatomic, readonly, assign) NSArray *ascendingSortedArray;
@property (nonatomic, readonly, assign) NSArray *descendingSortedArray;
@property (nonatomic, readonly, assign) NSArray *sortedArray;
- (NSArray *)ascendingSortedArrayWithSorter:(id<SCSorter>)sorter;
- (NSArray *)descendingSortedArrayWithSorter:(id<SCSorter>)sorter;
- (NSArray *)sortedArrayWithSorter:(id<SCSorter>)sorter;

Также категория объявляет ряд методов для создания и инициализации массивов с отсортированными данными из указанных существующих коллекций любого поддерживаемого библиотекой типа:

+ (instancetype)arrayWithAscendingSortedCollection:(id<SCCollection>)collection sorter:(id<SCSorter>)sorter;
+ (instancetype)arrayWithDescendingSortedCollection:(id<SCCollection>)collection sorter:(id<SCSorter>)sorter;
+ (instancetype)arrayWithSortedCollection:(id<SCCollection>)collection sorter:(id<SCSorter>)sorter;
+ (instancetype)arrayWithAscendingSortedCollection:(id<SCCollection>)collection;
+ (instancetype)arrayWithDescendingSortedCollection:(id<SCCollection>)collection;
+ (instancetype)arrayWithSortedCollection:(id<SCCollection>)collection;
- (instancetype)initWithAscendingSortedCollection:(id<SCCollection>)collection sorter:(id<SCSorter>)sorter;
- (instancetype)initWithDescendingSortedCollection:(id<SCCollection>)collection sorter:(id<SCSorter>)sorter;
- (instancetype)initWithSortedCollection:(id<SCCollection>)collection sorter:(id<SCSorter>)sorter;
- (instancetype)initWithAscendingSortedCollection:(id<SCCollection>)collection;
- (instancetype)initWithDescendingSortedCollection:(id<SCCollection>)collection;
- (instancetype)initWithSortedCollection:(id<SCCollection>)collection;

Сравнение массивов

Кроме стандартных методов сравнения массивов категория NSArray(SCArray) реализует новые методы:

- (BOOL)isEqualToCollection:(id<SCCollection>)collection;

Получение новых массивов

Категория NSArray(SCArray) объявляет ряд методов для получения новых массивов с использованием объектов из уже существующих массивов:

- (NSArray *)arrayByAddingObjects:(id)object, ... NS_REQUIRES_NIL_TERMINATION;
- (NSArray *)arrayByAddingArray:(NSArray *)array;
- (NSArray *)arrayByAddingCollection:(id<SCCollection>)collection;

Расширение класса NSMutableArray

Категория NSMutableArray(SCMutableArray) дополняет класс NSMutableArray методами протоколов SCMutableCollection и SCMutableIndexedCollection, обеспечивая экземпляры класса совместимостью с механизмами коллекций. Совместимость с другими механизмами библиотеки наследуется классом NSMutableArray от класса NSArray и категории NSArray(SCArray).


Копирование массивов

Категория NSMutableArray(SCMutableArray) реализует следующие методу категории SCMutableCollection, выполняющие замену существующего содержимого массива:

- (void)setCollection:(id<SCCollection>)collection;
- (void)setObject:(id<SCCollectioning>)object;
- (void)setObjects:(id<SCCollectioning>)object, ...;

Также категория декларирует методы, заменяющие текущее содержимое массива отсортированными объектами существующих коллекций:

- (void)setAscendingSortedCollection:(id<SCCollection>)collection sorter:(id<SCSorter>)sorter;
- (void)setDescendingSortedCollection:(id<SCCollection>)collection sorter:(id<SCSorter>)sorter;
- (void)setSortedCollection:(id<SCCollection>)collection sorter:(id<SCSorter>)sorter;
- (void)setAscendingSortedCollection:(id<SCCollection>)collection;
- (void)setDescendingSortedCollection:(id<SCCollection>)collection;
- (void)setSortedCollection:(id<SCCollection>)collection;

Добавление элементов

Категория реализует следующие методы добавления объектов протокола SCMutableCollection:

- (void)addObjects:(id<SCCollectioning>)object, ...;
- (void)addCollection:(id<SCCollection>)collection;

Также категория NSMutableArray(SCMutableArray) объявляет метод addArray:, который добавляет в массив объекты из указанного массива:

- (void)addArray:(NSArray *)array;
NSMutableArray *array = [NSMutableArray arrayWithArray:@[ @200, @600, @800, @400]];
[array addArray:@[ @100, @500]];
NSLog( @"%@", array);
2017-06-08 09:59:42.981230+0300 libtest[84484:5850646] (
200,
600,
800,
400,
100,
500
)

Удаление элементов

Полную поддержку средств удаления объектов протокола SCMutableCollection обеспечивает реализация в категории NSMutableArray(SCMutableArray) следующих методов:

- (void)removeObjectsWithClass:(Class)oclass;
- (void)removeObjectsWithClassName:(NSString *)name;
- (void)removeCollection:(id<SCCollection>)collection;
- (void)removeObjects:(id<SCCollectioning>)object, ...;

Замена элементов массивов

Замена объектов массивов осуществляется следующими методами протокола SCMutableCollection, реализованными в категории NSMutableArray(SCMutableArray):

- (void)replaceObjectsAtIndexes:(NSIndexSet *)indexes withCollection:(id<SCCollection>)collection;
- (void)replaceObjectsInRange:(NSRange)range withObjects:(id<SCCollectioning>)object, ...;
- (void)replaceObjectsInRange:(NSRange)range withCollection:(id<SCCollection>)collection;

Сортировка массивов

Категория NSMutableArray(SCMutableArray) реализует следующие методы сортировки содержимого массивов:

- (void)sortAscendingWithSorter:(id<SCSorter>)sorter;
- (void)sortDescendingWithSorter:(id<SCSorter>)sorter;
- (void)sortWithSorter:(id<SCSorter>)sorter;
- (void)sortAscending;
- (void)sortDescending;
- (void)sort;

Дополнительные методы

Также категория NSMutableArray(SCMutableArray) декларирует следующие дополнительные методы:

- (void)copyObjectAtIndex:(SCIndex)index toIndex:(SCIndex)destination;
- (void)moveObjectAtIndex:(SCIndex)index toIndex:(SCIndex)destination;
- (void)reverse;

Расширение класса NSSet

Категория NSSet(SCSet) расширяет возможности стандартных неупорядоченных множеств как для взаимодействия с различными механизами библиотеки, так и для обеспечения совместимости с коллекциями библиотеки в целом и неупорядоченными множествами SCSet в частности:


Создание неупорядоченных множеств

Категория NSSet(SCSet) реализует следующие классовые методы для создания неупорядоченных множеств на основании данных из последовательных файлов, словарей, потоков и объектов данных:

+ (instancetype)setWithCoder:(NSCoder *)coder;
+ (instancetype)setWithContentsOfSerializedFile:(NSString *)path;
+ (instancetype)setWithDataDictionary:(NSDictionary *)dictionary;
+ (instancetype)setWithDataDictionaryFromFile:(NSString *)path;
+ (instancetype)setWithStream:(SCStream *)stream;
+ (instancetype)setWithFileStream:(NSString *)path;
+ (instancetype)setWithData:(NSData *)data;
+ (instancetype)setWithContentsOfFile:(NSString *)path;
+ (instancetype)setWithContentsOfURL:(NSURL *)url;
+ (instancetype)setWithContentsOfURLString:(NSString *)urlString;

Категория декларирует следующие классовые методы создания неупорядоченных множеств:

+ (instancetype)setWithCollection:(id<SCCollection>)collection;

Инициализация неупорядоченных множеств

Категория объявляет дополнительные методы инициализации неупорядоченных множеств:

- (instancetype)initWithCollection:(id<SCCollection>)collection;

Реализация протокола SCCollection

В рамках реализации протокола SCCollection категория NSSet(SCSet) декларирует следующие свойства:

@property (nonatomic, readonly, retain) NSString *name;
@property (nonatomic, readonly, assign) BOOL empty;
@property (nonatomic, readonly, assign) BOOL readOnly;
@property (nonatomic, readonly, retain) id<SCCollectionDelegate> delegate;

Также категория реализует свойства протокола SCCollection, служащие для определения принадлежности экземпляра класса к тому или иному типу коллекций:

@property (nonatomic, readonly, assign) SCCollectionType collectionType;
@property (nonatomic, readonly, assign) BOOL isCollection;
@property (nonatomic, readonly, assign) BOOL isLibraryCollection;
@property (nonatomic, readonly, assign) BOOL isFoundationCollection;
@property (nonatomic, readonly, assign) BOOL isArray;
@property (nonatomic, readonly, assign) BOOL isLibraryArray;
@property (nonatomic, readonly, assign) BOOL isFoundationArray;
@property (nonatomic, readonly, assign) BOOL isSet;
@property (nonatomic, readonly, assign) BOOL isLibrarySet;
@property (nonatomic, readonly, assign) BOOL isFoundationSet;
@property (nonatomic, readonly, assign) BOOL isOrderedSet;
@property (nonatomic, readonly, assign) BOOL isLibraryOrderedSet;
@property (nonatomic, readonly, assign) BOOL isFoundationOrderedSet;
@property (nonatomic, readonly, assign) BOOL isDictionary;
@property (nonatomic, readonly, assign) BOOL isLibraryDictionary;
@property (nonatomic, readonly, assign) BOOL isFoundationDictionary;
@property (nonatomic, readonly, assign) BOOL isStack;
@property (nonatomic, readonly, assign) BOOL isQueue;
@property (nonatomic, readonly, assign) BOOL isList;
@property (nonatomic, readonly, assign) BOOL isSortable;

Свойство collectionType экземпляров классов NSSet и NSMutableSet всегда возвращает значение SCCollectionFoundationSet.

Для стандартных неупорядоченных множеств значение YES возвращают методы isCollection, isFoundationCollection, isSet и isFoundationSet. Остальные методы возвращают значение NO.


Поиск объектов

Категория NSSet(SCSet) реализует следующие методы поиска объкетов протокола SCCollection:

- (BOOL)containsObjects:(id<SCCollectioning>)object, ...;
- (BOOL)containsCollection:(id<SCCollection>)collection;
- (BOOL)containsAnyObject:(id<SCCollectioning>)object, ...;
- (BOOL)containsAnyObjectFromCollection:(id<SCCollection>)collection;

Преобразование неупорядоченных множеств

Категория декларирует и реализует свойства для преобразования неупорядоченных множеств в коллекции другого типа из поддерживаемых библиотекой:

@property (nonatomic, readonly, assign) SCArray *array;
@property (nonatomic, readonly, assign) SCSet *set;
@property (nonatomic, readonly, assign) SCOrderedSet *orderedSet;
@property (nonatomic, readonly, assign) SCDictionary *dictionary;
@property (nonatomic, readonly, assign) SCStack *stack;
@property (nonatomic, readonly, assign) SCQueue *queue;
@property (nonatomic, readonly, assign) SCUnidirectionalList *unidirectionalList;
@property (nonatomic, readonly, assign) SCBidirectionalList *bidirectionalList;
@property (nonatomic, readonly, assign) NSArray *foundationArray;
@property (nonatomic, readonly, assign) NSSet *foundationSet;
@property (nonatomic, readonly, assign) NSOrderedSet *foundationOrderedSet;
@property (nonatomic, readonly, assign) NSDictionary *foundationDictionary;

Сравнение неупорядоченных множеств

Кроме стандартных методов сравнения неупорядоченных множеств категория NSSet(SCSet) реализует новые методы:

- (BOOL)isEqualToCollection:(id<SCCollection>)collection;

Получение новых неупорядоченных множеств

Категория NSSet(SCSet) реализует ряд методов для получения новых неупорядоченных множеств с использованием объектов уже существующих неупорядоченных множеств:

- (NSSet *)setByAddingObjects:(id)object, ...;
- (NSSet *)setByAddingArray:(NSArray *)array;
- (NSSet *)setByAddingSet:(NSSet *)set;
- (NSSet *)setByAddingCollection:(id<SCCollection>)collection;

Расширение класса NSMutableSet

Категория NSMutableSet(SCMutableSet) расширяет функциональные возможности класса NSMutableSet (изменяемые неупорядоченные множества) через реализацию протокола SCMutableCollection:


Копирование неупорядоченных множеств

Категория реализует следующие методы копирования неупорядоченных множеств протокола SCMutableCollection:

- (void)setCollection:(id<SCCollection>)collection;
- (void)setObject:(id<SCCollectioning>)object;
- (void)setObjects:(id<SCCollectioning>)object, ...;

Добавление элементов

Категория NSMutableSet(SCMutableSet) реализует следующие методы добавления объектов в неупорядоченные множества из протокола SCMutableCollection:

- (void)addObjects:(id<SCCollectioning>)object, ...;
- (void)addCollection:(id<SCCollection>)collection;

Также в категории объявлены следующие методы добавления объектов:

- (void)addArray:(NSArray *)array;
- (void)addObjectsFromSet:(NSSet *)set;
- (void)addSet:(NSSet *)set;

Удаление элементов

Категория декларирует следующие методы удаления объектов:

- (void)removeObjectsWithClass:(Class)oclass;
- (void)removeObjectsWithClassName:(NSString *)name;
- (void)removeCollection:(id<SCCollection>)collection;
- (void)removeObjects:(id<SCCollectioning>)object, ...;

Расширение класса NSOrderedSet

Категория NSOrderedSet(SCOrderedSet) дополняет возможности упорядоченного множества методами и свойствами протоколов SCCollection и SCIndexedCollection:


Создание упорядоченных множеств

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

+ (instancetype)orderedSetWithCoder:(NSCoder *)coder;
+ (instancetype)orderedSetWithContentsOfSerializedFile:(NSString *)path;
+ (instancetype)orderedSetWithDataDictionary:(NSDictionary *)dictionary;
+ (instancetype)orderedSetWithDataDictionaryFromFile:(NSString *)path;
+ (instancetype)orderedSetWithStream:(SCStream *)stream;
+ (instancetype)orderedSetWithFileStream:(NSString *)path;
+ (instancetype)orderedSetWithData:(NSData *)data;
+ (instancetype)orderedSetWithContentsOfFile:(NSString *)path;
+ (instancetype)orderedSetWithContentsOfURL:(NSURL *)url;
+ (instancetype)orderedSetWithContentsOfURLString:(NSString *)urlString;

Также категория реализует следующие методы создания экземпляров классов:

+ (instancetype)orderedSetWithCollection:(id<SCCollection>)collection;

Инициализация упорядоченных множеств

- (instancetype)initWithCollection:(id<SCCollection>)collection;

Реализация протокола SCCollection

Категория NSOrderedSet(SCOrderedSet) декларирует следующие свойства протокола SCCollection:

@property (nonatomic, readonly, retain) NSString *name;
@property (nonatomic, readonly, assign) BOOL empty;
@property (nonatomic, readonly, assign) BOOL readOnly;
@property (nonatomic, readonly, retain) id<SCCollectionDelegate> delegate;

Следующие свойства категории NSOrderedSet(SCOrderedSet) и протокола SCCollection определяют тип коллекции, к которой относится экземпляр класса:

@property (nonatomic, readonly, assign) SCCollectionType collectionType;
@property (nonatomic, readonly, assign) BOOL isCollection;
@property (nonatomic, readonly, assign) BOOL isLibraryCollection;
@property (nonatomic, readonly, assign) BOOL isFoundationCollection;
@property (nonatomic, readonly, assign) BOOL isArray;
@property (nonatomic, readonly, assign) BOOL isLibraryArray;
@property (nonatomic, readonly, assign) BOOL isFoundationArray;
@property (nonatomic, readonly, assign) BOOL isSet;
@property (nonatomic, readonly, assign) BOOL isLibrarySet;
@property (nonatomic, readonly, assign) BOOL isFoundationSet;
@property (nonatomic, readonly, assign) BOOL isOrderedSet;
@property (nonatomic, readonly, assign) BOOL isLibraryOrderedSet;
@property (nonatomic, readonly, assign) BOOL isFoundationOrderedSet;
@property (nonatomic, readonly, assign) BOOL isDictionary;
@property (nonatomic, readonly, assign) BOOL isLibraryDictionary;
@property (nonatomic, readonly, assign) BOOL isFoundationDictionary;
@property (nonatomic, readonly, assign) BOOL isStack;
@property (nonatomic, readonly, assign) BOOL isQueue;
@property (nonatomic, readonly, assign) BOOL isList;
@property (nonatomic, readonly, assign) BOOL isSortable;

Свойство collectionType экземпляров классов NSOrderedSet и NSMutableOrderedSet всегда возвращает значение SCCollectionFoundationOrderedSet.

Значение YES возвращают методы isCollection, isFoundationCollection, isOrderedSet и isFoundationOrderedSet.


Поиск объектов

Категория NSOrderedSet(SCOrderedSet) реализует следующие свойства и методы протокола SCCollection:

@property (nonatomic, readonly, assign) SCIndex indexOfLastObject;
- (BOOL)containsObjects:(id<SCCollectioning>)object, ...;
- (BOOL)containsCollection:(id<SCCollection>)collection;
- (BOOL)containsAnyObject:(id<SCCollectioning>)object, ...;
- (BOOL)containsAnyObjectFromCollection:(id<SCCollection>)collection;

Преобразование упорядоченных множеств

Категория NSOrderedSet(SCOrderedSet) осуществляет реализацию свойства для конвертации между различными поддерживаемыми библиотекой типами коллекций протокола SCCollection:

@property (nonatomic, readonly, assign) SCArray *libraryArray;
@property (nonatomic, readonly, assign) SCSet *set;
@property (nonatomic, readonly, assign) SCOrderedSet *orderedSet;
@property (nonatomic, readonly, assign) SCDictionary *dictionary;
@property (nonatomic, readonly, assign) SCStack *stack;
@property (nonatomic, readonly, assign) SCQueue *queue;
@property (nonatomic, readonly, assign) SCUnidirectionalList *unidirectionalList;
@property (nonatomic, readonly, assign) SCBidirectionalList *bidirectionalList;
@property (nonatomic, readonly, assign) NSArray *foundationArray;
@property (nonatomic, readonly, assign) NSSet *foundationSet;
@property (nonatomic, readonly, assign) NSOrderedSet *foundationOrderedSet;
@property (nonatomic, readonly, assign) NSDictionary *foundationDictionary;

Сортировка упорядоченных множеств

Категория NSOrderedSet(SCOrderedSet) определяет свойства и методы, возвращающие отсортированные упорядоченные множества:

@property (nonatomic, readonly, assign) NSOrderedSet *ascendingSortedOrderedSet;
@property (nonatomic, readonly, assign) NSOrderedSet *descendingSortedOrderedSet;
@property (nonatomic, readonly, assign) NSOrderedSet *sortedOrderedSet;
- (NSOrderedSet *)ascendingSortedOrderedSetWithSorter:(id<SCSorter>)sorter;
- (NSOrderedSet *)descendingSortedOrderedSetWithSorter:(id<SCSorter>)sorter;
- (NSOrderedSet *)sortedOrderedSetWithSorter:(id<SCSorter>)sorter;

Также категория декларирует классовые методы и методы инициализации упорядоченных множеств с отсортированными данными из существующих коллекций любого поддерживаемого библиотекой типа:

+ (instancetype)orderedSetWithAscendingSortedCollection:(id<SCCollection>)collection sorter:(id<SCSorter>)sorter;
+ (instancetype)orderedSetWithDescendingSortedCollection:(id<SCCollection>)collection sorter:(id<SCSorter>)sorter;
+ (instancetype)orderedSetWithSortedCollection:(id<SCCollection>)collection sorter:(id<SCSorter>)sorter;
+ (instancetype)orderedSetWithAscendingSortedCollection:(id<SCCollection>)collection;
+ (instancetype)orderedSetWithDescendingSortedCollection:(id<SCCollection>)collection;
+ (instancetype)orderedSetWithSortedCollection:(id<SCCollection>)collection;
- (instancetype)initWithAscendingSortedCollection:(id<SCCollection>)collection sorter:(id<SCSorter>)sorter;
- (instancetype)initWithDescendingSortedCollection:(id<SCCollection>)collection sorter:(id<SCSorter>)sorter;
- (instancetype)initWithSortedCollection:(id<SCCollection>)collection sorter:(id<SCSorter>)sorter;
- (instancetype)initWithAscendingSortedCollection:(id<SCCollection>)collection;
- (instancetype)initWithDescendingSortedCollection:(id<SCCollection>)collection;
- (instancetype)initWithSortedCollection:(id<SCCollection>)collection;

Сравнение упорядоченных множеств

Кроме стандартных методов сравнения упорядоченных множеств категория NSOrderedSet(SCOrderedSet) реализует новые методы:

- (BOOL)isEqualToCollection:(id<SCCollection>)collection;

Получение новых упорядоченных множеств

Категория NSOrderedSet(SCOrderedSet) объявляет следующие методы для получения новых упорядоченных множеств:

- (NSOrderedSet *)orderedSetByAddingObject:(id)object;
- (NSOrderedSet *)orderedSetByAddingObjects:(id)object, ... NS_REQUIRES_NIL_TERMINATION;
- (NSOrderedSet *)orderedSetByAddingCollection:(id<SCCollection>)collection;
- (NSOrderedSet *)orderedSetByAddingArray:(NSArray *)array;
- (NSOrderedSet *)orderedSetByAddingSet:(NSSet *)set;
- (NSOrderedSet *)orderedSetByAddingOrderedSet:(NSOrderedSet *)orderedSet;

Дополнительные методы

Категория NSOrderedSet(SCOrderedSet) также реализует следующие свойства, которые мы затрудняемся отнести к той или иной группе:

@property (nonatomic, readonly, assign) NSArray* allObjects;

Расширение класса NSMutableOrderedSet

Категория NSMutableOrderedSet(SCMutableOrderedSet) дополняет стандартный класс изменяемых упорядоченных множеств функциональностью протоколов SCMutableCollection и SCMutableIndexedCollection:


Копирование упорядоченных множеств

Для реализации методов копирования коллекций протокола SCMutableCollection категория NSMutableOrderedSet(SCMutableOrderedSet) реализует эти методы в классе NSMutableOrderedSet:

- (void)setSet:(NSSet *)set;
- (void)setOrderedSet:(NSOrderedSet *)orderedSet;
- (void)setCollection:(id<SCCollection>)collection;
- (void)setObject:(id<SCCollectioning>)object;
- (void)setObjects:(id<SCCollectioning>)object, ...;

Добавление элементов

Реализация функций добавления объектов протокола SCMutableCollection заключается в объявлении категорией NSMutableOrderedSet(SCMutableOrderedSet) следующих методов:

- (void)addObjects:(id<SCCollectioning>)object, ...;
- (void)addCollection:(id<SCCollection>)collection;
- (void)addArray:(NSArray *)array;
- (void)addObjectsFromSet:(NSSet *)set;
- (void)addSet:(NSSet *)set;
- (void)addObjectsFromOrderedSet:(NSOrderedSet *)orderedSet;
- (void)addOrderedSet:(NSOrderedSet *)orderedSet;

Удаление элементов

Категория реализует следующие методы удаления объектов протокола SCMutableCollection:

- (void)removeObjectsWithClass:(Class)oclass;
- (void)removeObjectsWithClassName:(NSString *)name;
- (void)removeCollection:(id<SCCollection>)collection;
- (void)removeObjects:(id<SCCollectioning>)object, ...;

Замена элементов

Категория NSMutableOrderedSet(SCMutableOrderedSet) реализует следующие методы замены элементов упорядоченного множества:

- (void)replaceObjectsAtIndexes:(NSIndexSet *)indexes withCollection:(id<SCCollection>)collection;

Сортировка упорядоченных множеств

Сортировка объектов упорядоченного множества осуществляется следующими методами категории:

- (void)sortAscendingWithSorter:(id<SCSorter>)sorter;
- (void)sortDescendingWithSorter:(id<SCSorter>)sorter;
- (void)sortWithSorter:(id<SCSorter>)sorter;
- (void)sortAscending;
- (void)sortDescending;
- (void)sort;

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

- (void)setAscendingSortedCollection:(id<SCCollection>)collection sorter:(id<SCSorter>)sorter;
- (void)setDescendingSortedCollection:(id<SCCollection>)collection sorter:(id<SCSorter>)sorter;
- (void)setSortedCollection:(id<SCCollection>)collection sorter:(id<SCSorter>)sorter;
- (void)setAscendingSortedCollection:(id<SCCollection>)collection;
- (void)setDescendingSortedCollection:(id<SCCollection>)collection;
- (void)setSortedCollection:(id<SCCollection>)collection;

Дополнительные методы

Кроме вышепечисленных методов категория NSMutableOrderedSet(SCMutableOrderedSet) реализует методы, которые мы не можем отнести к конкретной категории методов:

- (void)moveObjectAtIndex:(SCIndex)index toIndex:(SCIndex)destination;

Расширение класса NSDictionary

Категория NSDictionary(SCDictionary) расширяет стандартную функциональность класса NSDictionary путем добавления в него поддержки протокола SCCollection. Данные расширения не только добавляют стандартному классу дополнительные возможности, но и делают словари совместимыми с различными механизмами нашей библиотеки:


Создание словарей

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

+ (instancetype)dictionaryWithCoder:(NSCoder *)coder;
+ (instancetype)dictionaryWithContentsOfSerializedFile:(NSString *)path;
+ (instancetype)dictionaryWithDataDictionary:(NSDictionary *)dictionary;
+ (instancetype)dictionaryWithDataDictionaryFromFile:(NSString *)path;
+ (instancetype)dictionaryWithStream:(SCStream *)stream;
+ (instancetype)dictionaryWithFileStream:(NSString *)path;
+ (instancetype)dictionaryWithData:(NSData *)data;
+ (instancetype)dictionaryWithContentsOfURLString:(NSString *)urlString;

Категория декларирует следующие методы создания словарей:

+ (instancetype)dictionaryWithCollection:(id<SCCollection>)collection;

Инициализация словарей

Категория NSDictionary(SCDictionary) объявляет следующие методы инициализации экземпляров класса:

- (instancetype)initWithCollection:(id<SCCollection>)collection;

Реализация протокола SCCollection

Для реализации ряда методов протокола SCCollection категория объявляет следующие свойства:

@property (nonatomic, readonly, retain) NSString *name;
@property (nonatomic, readonly, assign) BOOL empty;
@property (nonatomic, readonly, assign) BOOL readOnly;
@property (nonatomic, readonly, retain) id<SCCollectionDelegate> delegate;

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

@property (nonatomic, readonly, assign) SCCollectionType collectionType;
@property (nonatomic, readonly, assign) BOOL isCollection;
@property (nonatomic, readonly, assign) BOOL isLibraryCollection;
@property (nonatomic, readonly, assign) BOOL isFoundationCollection;
@property (nonatomic, readonly, assign) BOOL isArray;
@property (nonatomic, readonly, assign) BOOL isLibraryArray;
@property (nonatomic, readonly, assign) BOOL isFoundationArray;
@property (nonatomic, readonly, assign) BOOL isSet;
@property (nonatomic, readonly, assign) BOOL isLibrarySet;
@property (nonatomic, readonly, assign) BOOL isFoundationSet;
@property (nonatomic, readonly, assign) BOOL isOrderedSet;
@property (nonatomic, readonly, assign) BOOL isLibraryOrderedSet;
@property (nonatomic, readonly, assign) BOOL isFoundationOrderedSet;
@property (nonatomic, readonly, assign) BOOL isDictionary;
@property (nonatomic, readonly, assign) BOOL isLibraryDictionary;
@property (nonatomic, readonly, assign) BOOL isFoundationDictionary;
@property (nonatomic, readonly, assign) BOOL isStack;
@property (nonatomic, readonly, assign) BOOL isQueue;
@property (nonatomic, readonly, assign) BOOL isList;
@property (nonatomic, readonly, assign) BOOL isSortable;

Свойство collectionType экземпляров классов NSDictionary и NSMutableDictionary всегда возвращает значение SCCollectionFoundationDictionary.

Для экземпляров классов NSDictionary и NSMutableDictionary значение YES возвращают методы isCollection, isFoundationCollection, isDictionary и isFoundationDictionary. Остальные методы возвращают значение NO.


Поиск объектов и ключей

Категория декларирует следующие методы поиска объектов протокола <SCCollection>:

- (BOOL)containsObject:(id<SCCollectioning>)object;
- (BOOL)containsObjects:(id<SCCollectioning>)object, ...;
- (BOOL)containsCollection:(id<SCCollection>)collection;
- (BOOL)containsAnyObject:(id<SCCollectioning>)object, ...;
- (BOOL)containsAnyObjectFromCollection:(id<SCCollection>)collection;

Также категория NSDictionary(SCDictionary) реализует методы для поиска ключей объектов:

- (BOOL)containsKey:(id)key;
- (BOOL)containsKeys:(id)key, ... NS_REQUIRES_NIL_TERMINATION;
- (BOOL)containsKeysFromCollection:(id<SCCollection>)collection;
- (BOOL)containsAnyKey:(id)key, ... NS_REQUIRES_NIL_TERMINATION;
- (BOOL)containsAnyKeyFromCollection:(id<SCCollection>)collection;

Доступ к ключам и значениям

Метод getObjectForKey: создает и возвращает объект с указанным ключем, сохраненный в формате словарей данных, который обеспечивает запись в словарь данных о типах ключа и объекта.


Преобразование словарей

Преобразование словарей в другие виды коллекций выполняют следующие свойства категории:

@property (nonatomic, readonly, assign) SCArray *array;
@property (nonatomic, readonly, assign) SCSet *set;
@property (nonatomic, readonly, assign) SCOrderedSet *orderedSet;
@property (nonatomic, readonly, assign) SCDictionary *dictionary;
@property (nonatomic, readonly, assign) SCStack *stack;
@property (nonatomic, readonly, assign) SCQueue *queue;
@property (nonatomic, readonly, assign) SCUnidirectionalList *unidirectionalList;
@property (nonatomic, readonly, assign) SCBidirectionalList *bidirectionalList;
@property (nonatomic, readonly, assign) NSArray *foundationArray;
@property (nonatomic, readonly, assign) NSSet *foundationSet;
@property (nonatomic, readonly, assign) NSOrderedSet *foundationOrderedSet;
@property (nonatomic, readonly, assign) NSDictionary *foundationDictionary;

Сравнение словарей

Кроме стандартных методов сравнения словарей категория NSDictionary(SCDictionary) реализует новые методы:

- (BOOL)isEqualToCollection:(id<SCCollection>)collection;

Получение новых словарей

Категория NSDictionary(SCDictionary) реализует следующие методы для получения новых словарей с использованием данных из существующих словарей:

- (NSDictionary *)dictionaryByAddingObject:(id)object forKey:(id)key;
- (NSDictionary *)dictionaryByAddingObject:(id)object;
- (NSDictionary *)dictionaryByAddingObjects:(NSArray *)objects forKeys:(NSArray *)keys;
- (NSDictionary *)dictionaryByAddingObjects:(id)object, ...;
- (NSDictionary *)dictionaryByAddingObjectsAndKeys:(id)object, ...;
- (NSDictionary *)dictionaryByAddingCollection:(id<SCCollection>)collection;
- (NSDictionary *)dictionaryByAddingObjectsFromArray:(NSArray *)array;
- (NSDictionary *)dictionaryByAddingArray:(NSArray *)array;
- (NSDictionary *)dictionaryByAddingEntriesFromDictionary:(NSDictionary *)dictionary;
- (NSDictionary *)dictionaryByAddingDictionary:(NSDictionary *)dictionary;

Расширение класса NSMutableDictionary

Категория NSMutableDictionary(SCMutableDictionary) дополняет класс NSMutableDictionary функциональными возможностями протокола SCMutableCollection:


Копирование словарей

Категория реализует следующие методы протокола SCMutableCollection:

- (void)setCollection:(id<SCCollection>)collection;
- (void)setObject:(id<SCCollectioning>)object;
- (void)setObjects:(id<SCCollectioning>)object, ...;

Добавление элементов

Категория реализует следующие методы протокола SCMutableCollection для удаления объектов из словаря. При работе данных методов ключи к новым объектам генерируются автоматически (кроме ряда случаев с методом addCollection:).

- (void)addObject:(id<SCCollectioning>)object;
- (void)addObjects:(id<SCCollectioning>)object, ...;
- (void)addCollection:(id<SCCollection>)collection;
- (void)addObjectsFromArray:(NSArray *)array;
- (void)addArray:(NSArray *)array;
- (void)addDictionary:(NSDictionary *)dictionary;
- (void)addObjects:(id<SCCollection>)objects forKeys:(id<SCCollection>)keys;
- (void)addObjectsAndKeys:(id)object, ...;
- (void)addObject:(id<SCDictionaring>)object forKey:(NSString *)key;

Удаление элементов

Для удаления объектов категория NSMutableDictionary(SCMutableDictionary) реализует следующие методы протокола SCMutableCollection:

- (void)removeObjectsWithClass:(Class)oclass;
- (void)removeObjectsWithClassName:(NSString *)name;
- (void)removeCollection:(id<SCCollection>)collection;
- (void)removeObject:(id<SCCollectioning>)object;
- (void)removeObjects:(id<SCCollectioning>)object, ...;

Расширение класса NSData

Как и категории NSNull(SCNull) и NSDate(SCDate), категория NSData(SCData) расширяет функциональность класса NSData методами для создания экземпляров класса с использованием данных из последовательных файлов, словарей, потоков и объектов данных:

+ (instancetype)dataWithCoder:(NSCoder *)coder;
+ (instancetype)dataWithContentsOfSerializedFile:(NSString *)path;
+ (instancetype)dataWithDataDictionary:(NSDictionary *)dictionary;
+ (instancetype)dataWithDataDictionaryFromFile:(NSString *)path;
+ (instancetype)dataWithStream:(SCStream *)stream;
+ (instancetype)dataWithFileStream:(NSString *)path;
+ (instancetype)dataWithContentsOfURLString:(NSString *)urlString;

Расширение класса NSIndexSet

Категория NSIndexSet(SCIndexSet) расширяет функциональность класса NSIndexSet классовыми методами с применением данных из последовательных файлов, словарей, потоков и объектов данных:

+ (instancetype)indexSetWithCoder:(NSCoder *)coder;
+ (instancetype)indexSetWithContentsOfSerializedFile:(NSString *)path;
+ (instancetype)indexSetWithDataDictionary:(NSDictionary *)dictionary;
+ (instancetype)indexSetWithDataDictionaryFromFile:(NSString *)path;
+ (instancetype)indexSetWithStream:(SCStream *)stream;
+ (instancetype)indexSetWithFileStream:(NSString *)path;
+ (instancetype)indexSetWithData:(NSData *)data;
+ (instancetype)indexSetWithContentsOfFile:(NSString *)path;
+ (instancetype)indexSetWithContentsOfURL:(NSURL *)url;
+ (instancetype)indexSetWithContentsOfURLString:(NSString *)urlString;

Также категория объявляет следующие методы создания экземпляров класса:

+ (instancetype)indexSetWithIndexSet:(NSIndexSet *)indexSet;

Классы и категории macOS

Предупреждения
Описанные в данном разделе классы и категории поддерживаются только в операционной системе macOS и ограниченно на платформе GNUstep.

К данным компонентам библиотеки относятся следующие классы и категории:


Категория NSButton(SCButton)

Категория NSButton(SCButton) добавляет в стандартный класс NSButton следующее свойство:

@property (nonatomic, readwrite, assign) BOOL boolState;

Данное свойство позволяет переключать состояние интерфейсной кнопки с помощью логического значения:


Категория NSAlert(SCAlert)

Стандартный класс NSAlert предоставляет программистам интерфейс для отображения панелей с различными сообщениями и возможностями выбора действий со стороны пользователя. Пример панели в виде запроса на подтверждение удаления данных Вы видите на следующем рисунке:

sample_11_01_ru.png

Несмотря на свои возможности, класс NSAlert для работы с ним требует от программистов задания значительного числа параметров, что делает данный класс не самым удобным в использовании. Именно для решения данной проблемы мы и разработали наше собственное расширение в виде категории NSAlert(SCAlert). Данный раздел документации подробно рассматривает наши дополнения к классу:


Виды панелей

Операционная система macOS определяет следующие виды панелей:

NSAlertStyleCritical - панель с критической информацией, например с сообщением об ошибке
NSAlertStyleWarning - преждупреждающая панель, выводящая информацию средней степени важности
NSAlertStyleInformational - информационная панель, предназначенная для вывода простого сообщения

Создание и инициализация панелей

Для создания панели общего вида категория объявляет следующий метод:

+ (instancetype)alertWithStyle:(NSAlertStyle)style
message:(NSString *)message
text:(NSString *)text
buttons:(NSString *)button, ... NS_REQUIRES_NIL_TERMINATION;

Метод возвращает указатель на панель с заданными стилем, текстом сообщения, информационным текстом и списком кнопок. Для отображения вышеприведенного примера панели можно использовать следующий код:

NSAlert *alert = [NSAlert criticalAlertWithMessage:@"Confirm the deleting of the selected user:"
text:@"John Smith"
buttons:@"Yes", @"No", @"Help", nil];
[alert runModal];

Приведем описание остальных методов создания панелей:

+ (instancetype)criticalAlertWithMessage:(NSString *)message
text:(NSString *)text
buttons:(NSString *)button, ... NS_REQUIRES_NIL_TERMINATION;
+ (instancetype)criticalAlertWithMessage:(NSString *)message text:(NSString *)text button:(NSString *)button;
+ (instancetype)criticalAlertWithMessage:(NSString *)message text:(NSString *)text;
+ (instancetype)warningAlertWithMessage:(NSString *)message
text:(NSString *)text
buttons:(NSString *)button, ... NS_REQUIRES_NIL_TERMINATION;
+ (instancetype)warningAlertWithMessage:(NSString *)message text:(NSString *)text button:(NSString *)button;
+ (instancetype)warningAlertWithMessage:(NSString *)message text:(NSString *)text;
+ (instancetype)alertWithMessage:(NSString *)message
text:(NSString *)text
buttons:(NSString *)button, ... NS_REQUIRES_NIL_TERMINATION;
+ (instancetype)alertWithMessage:(NSString *)message text:(NSString *)text button:(NSString *)button;
+ (instancetype)alertWithMessage:(NSString *)message text:(NSString *)text;

Также категория NSAlert(SCAlert) объявляет следующие методы инициализации различных видов панелей:

- (instancetype)initWithStyle:(NSAlertStyle)style
message:(NSString *)message
text:(NSString *)text
buttons:(NSString *)button, ... NS_REQUIRES_NIL_TERMINATION;
- (instancetype)initCriticalAlertWithMessage:(NSString *)message
text:(NSString *)text
buttons:(NSString *)button, ... NS_REQUIRES_NIL_TERMINATION;
- (instancetype)initCriticalAlertWithMessage:(NSString *)message text:(NSString *)text button:(NSString *)button;
- (instancetype)initCriticalAlertWithMessage:(NSString *)message text:(NSString *)text;
- (instancetype)initWarningAlertWithMessage:(NSString *)message
text:(NSString *)text
buttons:(NSString *)button, ... NS_REQUIRES_NIL_TERMINATION;
- (instancetype)initWarningAlertWithMessage:(NSString *)message text:(NSString *)text button:(NSString *)button;
- (instancetype)initWarningAlertWithMessage:(NSString *)message text:(NSString *)text;
- (instancetype)initWithMessage:(NSString *)message
text:(NSString *)text
buttons:(NSString *)button, ... NS_REQUIRES_NIL_TERMINATION;
- (instancetype)initWithMessage:(NSString *)message text:(NSString *)text button:(NSString *)button;
- (instancetype)initWithMessage:(NSString *)message text:(NSString *)text;

Отображение панелей

Созданные панели можно вывести на экран с помощью метода NSAlert::runModal, однако категория NSAlert(SCAlert) декларирует ряд методов, которые выполняют следующие действия:

Данные методы объявлены в категории NSAlert(SCAlert) следующим образом:

+ (NSInteger)runAlertWithStyle:(NSAlertStyle)style
message:(NSString *)message
text:(NSString *)text
buttons:(NSString *)button, ... NS_REQUIRES_NIL_TERMINATION;
+ (NSInteger)runCriticalAlertWithMessage:(NSString *)message
text:(NSString *)text
buttons:(NSString *)button, ... NS_REQUIRES_NIL_TERMINATION;
+ (NSInteger)runCriticalAlertWithMessage:(NSString *)message text:(NSString *)text button:(NSString *)button;
+ (NSInteger)runCriticalAlertWithMessage:(NSString *)message text:(NSString *)text;
+ (NSInteger)runWarningAlertWithMessage:(NSString *)message
text:(NSString *)text
buttons:(NSString *)button, ... NS_REQUIRES_NIL_TERMINATION;
+ (NSInteger)runWarningAlertWithMessage:(NSString *)message text:(NSString *)text button:(NSString *)button;
+ (NSInteger)runWarningAlertWithMessage:(NSString *)message text:(NSString *)text;
+ (NSInteger)runAlertWithMessage:(NSString *)message
text:(NSString *)text
buttons:(NSString *)button, ... NS_REQUIRES_NIL_TERMINATION;
+ (NSInteger)runAlertWithMessage:(NSString *)message text:(NSString *)text button:(NSString *)button;
+ (NSInteger)runAlertWithMessage:(NSString *)message text:(NSString *)text;

Подробная информация о возвращаемых этими методами кодах нажатых пользователем кнопках приведена в разделе Кнопки панелей данного руководства.


Запрос подтверждений

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

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

Чтобы в данных простых случаях не добавлять в приложение проверку кода выбранной пользователем кнопки мы создали в категории NSAlert(SCAlert) ряд методов запроса подтверждений, основным из которых является метод:

+ (BOOL)confirmAlertWithStyle:(NSAlertStyle)style
message:(NSString *)message
text:(NSString *)text
confirm:(NSInteger)confirm
buttons:(NSString *)button, ... NS_REQUIRES_NIL_TERMINATION;

Данный метод создает и выводит на экран панель указанного стиля с заданными текстом сообщения, информационным текстом и списком заголовков кнопок. После того, как пользователь нажмет одну из кнопок, метод выполняет сравнение кода этой кнопки с кодом, который задан параметром confirm. Если коды совпадают, то метод возвращает значение YES, в противном случае возвращаетс значение NO.

Также категория NSAlert(SCAlert) объявляет следующие дополнительные методы запроса подтверждений:

+ (BOOL)confirmCriticalAlertWithMessage:(NSString *)message
text:(NSString *)text
confirm:(NSInteger)confirm
buttons:(NSString *)button, ... NS_REQUIRES_NIL_TERMINATION;
+ (BOOL)confirmCriticalAlertWithMessage:(NSString *)message
text:(NSString *)text
buttons:(NSString *)button, ... NS_REQUIRES_NIL_TERMINATION;
+ (BOOL)confirmWarningAlertWithMessage:(NSString *)message
text:(NSString *)text
confirm:(NSInteger)confirm
buttons:(NSString *)button, ... NS_REQUIRES_NIL_TERMINATION;
+ (BOOL)confirmWarningAlertWithMessage:(NSString *)message
text:(NSString *)text
buttons:(NSString *)button, ... NS_REQUIRES_NIL_TERMINATION;
+ (BOOL)confirmAlertWithMessage:(NSString *)message
text:(NSString *)text
confirm:(NSInteger)confirm
buttons:(NSString *)button, ... NS_REQUIRES_NIL_TERMINATION;
+ (BOOL)confirmAlertWithMessage:(NSString *)message
text:(NSString *)text
buttons:(NSString *)button, ... NS_REQUIRES_NIL_TERMINATION;

Обращаем Ваше внимание, что если метод не имеет параметра confirm, это означает, что в качестве подтверждающей кнопки используется первая из добавленых. Подробнее о работе с кнопками и их кодами Вы можете прочитать в следующем разделе.

Дополнительно категория NSAlert(SCAlert) реализует ряд простых методов для запроса подтверждений:

+ (BOOL)confirmYesNoAlertWithMessage:(NSString *)message text:(NSString *)text;
+ (BOOL)confirmNoYesAlertWithMessage:(NSString *)message text:(NSString *)text;
+ (BOOL)confirmOKCancelAlertWithMessage:(NSString *)message text:(NSString *)text;
+ (BOOL)confirmCancelOKAlertWithMessage:(NSString *)message text:(NSString *)text;

Кнопки панелей

Класс NSAlert предоставляет метод addButtonWithTitle:, который добавляет в существующую панель новую кнопку слева от ранее добавленных. По такому же алгоритму действуют и методы категории NSAlert(SCAlert), позволяющие указать несколько кнопок - первая кнопка в списке выводится самой правой, следующая за ней слева и так далее.

Метод NSAlert::runModal возвращает код выбранной пользователем кнопки, который вычисляется по формуле 1000 + id, где параметр id обозначает порядковый номер кнопки справа налево, начиная с нуля. То есть, самая правая кнопка имеет код возврата 1000, кнопка слева от нее код 1001 и так далее.

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

NSAlertFirstButtonReturn = 1000 // Самая правая кнопка панели
NSAlertSecondButtonReturn = 1001 // Вторая справа кнопка панели
NSAlertThirdButtonReturn = 1002 // Третья справа кнопка панели

Однако вы можете использовать свои собственные константы как для первых трех кнопок, так и для всех остальных, которые Вы будете при необходимости добавлять в Ваши панели.


Исключительные ситуации

Для эффективной обработки возможных ошибок библиотека использует классы исключительных ситуаций, общим предком которых является класс SCException (дочерний класс NSException). Данный раздел руководства программиста подробно рассказывает как об общих моментах всех классов исключительных ситуаций библиотеки, так и об особенностях ошибок тех или иных механизмов библиотеки.

Библиотека определяет следующие исключительные ситуации:


Иерархия классов исключительных ситуаций

exceptions.png

Категория NSException(SCException)

Категория NSException(SCException) добавляет в класс SCException поддержку последовательных файлов, словарей, потоков, объектов данных и коллекций:

+ (instancetype)exceptionWithCoder:(NSCoder *)coder;
+ (instancetype)exceptionWithContentsOfSerializedFile:(NSString *)path;
+ (instancetype)exceptionWithDataDictionary:(NSDictionary *)dictionary;
+ (instancetype)exceptionWithDataDictionaryFromFile:(NSString *)path;
+ (instancetype)exceptionWithStream:(SCStream *)stream;
+ (instancetype)exceptionWithFileStream:(NSString *)path;
+ (instancetype)exceptionWithData:(NSData *)data;
+ (instancetype)exceptionWithContentsOfFile:(NSString *)path;
+ (instancetype)exceptionWithContentsOfURL:(NSURL *)url;
+ (instancetype)exceptionWithContentsOfURLString:(NSString *)urlString;

Класс SCException

Класс SCException является общим предком всех классов исключительных ситуаций нашей библиотеки. Он не только создает иерархию классов, но и определяет для остальных классов такие понятия и средства, как коды и идентификаторы ошибок:


Коды и идентификаторы ошибок

Каждая ошибка в библиотеке имеет свои собственные код и идентификатор.

Код ошибки - отрицательное число, начиная от значения -20000 и ниже. Такой выбор связан с кодами ошибок, которые СУБД ORACLE выделяет для пользовательских ошибок. Собственно сама система формирования кодов и идентификаторов ошибок взята нами из ORACLE.

Для получения идентификатора ошибки используется свойство code:

@property (nonatomic, readonly, assign) SCInteger code;
@try {
NSLog( @"%@", array);
}
@catch (SCException *error) {
NSLog( @"%@", [error description]);
NSLog( @"========================================================================");
NSLog( @"Error code: %d", error.code);
NSLog( @"========================================================================");
}
2016-09-21 13:11:00.173 libtest[3362:472990] SCL-20041: Source collection is nil
2016-09-21 13:11:00.174 libtest[3362:472990] ========================================================================
2016-09-21 13:11:00.174 libtest[3362:472990] Error code: -20041
2016-09-21 13:11:00.174 libtest[3362:472990] ========================================================================

Идентификатором ошибки мы называем строку, которая обычно содержит три символа и текстовое представление кода ошибки. Для непосредственно ошибок библиотеки мы используем символы SCL. Чтобы получить идентификатор ошибки, необходимо воспользоваться свойством eid:

@property (nonatomic, readonly, retain) NSString *eid;
@try {
SCArray *array = [SCArray array];
[array addObject:nil];
NSLog( @"%@", array);
}
@catch (SCException *error) {
NSLog( @"%@", [error description]);
NSLog( @"========================================================================");
NSLog( @"Error ID: %@", error.eid);
NSLog( @"========================================================================");
}
2016-09-21 14:04:41.375 libtest[3803:499118] SCL-20044: Array - empty item adding attemption
2016-09-21 14:04:41.375 libtest[3803:499118] ========================================================================
2016-09-21 14:04:41.375 libtest[3803:499118] Error ID: SCL-20044
2016-09-21 14:04:41.375 libtest[3803:499118] ========================================================================

Инициализация исключительных ситуаций

Класс SCException объявляет следующие методы инициализации исключительных ситуаций:

- (instancetype)initWithName:(NSString *)name reason:(NSString *)reason code:(SCInteger)code eid:(NSString *)eid;

Класс SCAbstractMethodException

Класс SCAbstractMethodException создан специально для ситуаций, когда происходит попытка вызова абстрактного метода. Поскольку в Objective C такого понятия, как абстрактный метод нет, то приходится создавать реализацию такого метода с вызовом исключительной ситуации SCL-20001.

Класс объявляет следующие свойства для доступа к данным исключительной ситуации:

@property (nonatomic, readonly, retain) NSString *methodName;

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

+ (instancetype)exceptionWithMethod:(NSString *)method;

Класс SCSystemException

Класс исключительной ситуации SCSystemException предназначен для обработки ошибок, которые возникают при использовании системных вызовов или библиотек, использующих системные вызовы. Все системные ошибки идентифицируются библиотекой под идентификатором SCL-20002.

Класс декларирует следующие свойства и методы, обеспечивающие доступ к информации об обрабатываемой системной ошибке:

@property (nonatomic, assign, readonly, getter=error) SCSystemError error;
@property (nonatomic, retain, readonly, getter=objectName) NSString *objectName;

Для создания экземпляров класса в его интерфейсе декларированы следующие классовые методы:

+ (instancetype)exceptionWithError:(SCSystemError)error object:(NSString *)object;
+ (instancetype)exceptionWithError:(SCSystemError)error;

Класс SCNumberException

Класс SCNumberException реализует понятие ошибки числового объекта, которая может возникнуть при работе с методами расширяющей класс NSNumber категории NSNumber(SCNumber). В классе определены следующие идентификаторы ошибок:

Выполнить инициализацию ошибки числового объекта с заданными описанием, кодом и идентификатором можно с помощью следующего метода класса SCNumberException:

- (instancetype)initWithReason:(NSString *)reason code:(SCInteger)code eid:(NSString *)eid;

Неопределенная ошибка числового объекта

Ошибка SCL-20010 не используется библиотекой, однако ее можно использовать в тех случаях, когда необходимо обозначить ошибку числового объекта, но не вводить новый идентификатор ошибки.

Для создания и инициализации неопределенной ошибки числового объекта можно использовать следующие методы класса:

+ (instancetype)exception;

Неподдерживаемый тип числового объекта

Ошибка SCL-20011 генерируется при обнаружении числового объекта неподдерживаемого библитекой типа. При этом в ходе обработки данной ошибки можно использовать следующие свойства:

@property (nonatomic, readonly, retain) NSString *unsupportedType;

Для создания исключительной ситуации неподдерживаемого типа числового объекта применяются методы:

+ (instancetype)exceptionWithUnsupportedType:(NSString *)type;

Класс SCStreamException

Класс исключительной ситуации SCStreamException обеспечивает обработку ошибок механизма потоков:


Свойства исключительной ситуации

Класс SCStreamException декларирует следующие свойства и методы доступа к ним:

@property (nonatomic, readonly, retain) NSString *streamName;
@property (nonatomic, readonly, retain) NSString *unknown;
@property (nonatomic, readonly, retain) NSString *unexpected;
@property (nonatomic, readonly, retain) NSString *expected;
@property (nonatomic, readonly, retain) NSString *unsupported;
@property (nonatomic, readonly, assign) SCSize readedBytes;
@property (nonatomic, readonly, assign) SCSize writedBytes;
@property (nonatomic, readonly, assign) SCSize waitedBytes;
@property (nonatomic, readonly, assign) SCInteger openError;
@property (nonatomic, readonly, assign) SCInteger readError;
@property (nonatomic, readonly, assign) SCInteger writeError;
@property (nonatomic, readonly, assign) NSString *numberType;
@property (nonatomic, readonly, assign) SCFileStreamOpenMode openMode;
@property (nonatomic, readonly, assign) SCSystemError seekError;
@property (nonatomic, readonly, assign) NSInteger offset;
@property (nonatomic, readonly, assign) SCFileStreamOffsetWhence whence;

SCL-20020: неопределенная ошибка потока

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

При этом класс SCStreamException позволяет создать исключительную ситуацию с возможностью задать нестандартные коды и идентификаторы ошибки:

+ (instancetype)exceptionWithStream:(NSString *)stream
reason:(NSString *)reason
code:(SCInteger)code
eid:(NSString *)eid;
+ (instancetype)exceptionWithReason:(NSString *)reason code:(SCInteger)code eid:(NSString *)eid;

SCL-20021: поток не открыт

Данная ошибка возникает при попытке совершения операции чтения или записи с неоткрытым потоком.

Для создания данной исключительной ситуации используются классовые методы:

+ (instancetype)exceptionWithNotOpenStream:(NSString *)stream;
+ (instancetype)exceptionWithNotOpen;

SCL-20022: поток открыт только для чтения

Исключительная ситуация возникает при попытке записать данные в поток, который открыт только для чтения.

Для создания данной исключительной ситуации класс SCStreamException декларирует следующие классовые методы:

+ (instancetype)exceptionWithReadOnlyStream:(NSString *)stream;
+ (instancetype)exceptionWithReadOnly;

SCL-20023: поток открыт только для записи

Данная ошибка генерируется механизмом потоков при попытке чтения данных из открытого только для записи потока.

Создание данной исключительной ситуации возможно через использование следующих классовых методов

+ (instancetype)exceptionWithReadOnlyStream:(NSString *)stream;
+ (instancetype)exceptionWithReadOnly;

SCL-20024: обнаружен неизвестный класс

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

Получить название неизвестного класса можно через свойство unknown:

@property (nonatomic, readonly, retain) NSString *unknown;

Для создания экземпляров данной исключительной ситуации предназначены следующие классовые методы:

+ (instancetype)exceptionWithUnknown:(NSString *)name stream:(NSString *)stream;
+ (instancetype)exceptionWithUnknown:(NSString *)name;

SCL-20025: обнаружен экземпляр класса неожиданного типа

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

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

@property (nonatomic, readonly, retain) NSString *unexpected;
@property (nonatomic, readonly, retain) NSString *expected;

Для создания данной исключительной ситуации предназначены следующие классовые методы:

+ (instancetype)exceptionWithUnexpected:(NSString *)unexpected expected:(NSString *)expected stream:(NSString *)stream;
+ (instancetype)exceptionWithUnexpected:(NSString *)unexpected expected:(NSString *)expected;

SCL-20026: обнаружен неподдерживаемый класс

При загрузке данных экземпляра класса может обнаружиться, что данный класс не соответствует протоколу SCStreaming.

Название такого класса можно выяснить через свойство класса SCStreamException:

@property (nonatomic, readonly, retain) NSString *unsupported;

Для создания исключительной ситуации могут быть использованы следующие классовые методы:

+ (instancetype)exceptionWithUnsupported:(NSString *)name stream:(NSString *)stream;
+ (instancetype)exceptionWithUnsupported:(NSString *)name;

SCL-20027: операция чтения не завершена

Ошибка возникает в том случае, если из потока было загружено меньше символов, чем было запрошено.

Данные о том, сколько символов было прочитано, а сколько запрошено, можно получить с помощью следующих свойств:

@property (nonatomic, readonly, assign) SCSize readedBytes;
@property (nonatomic, readonly, assign) SCSize waitedBytes;

Создание экземпляров данной исключительной ситуации обеспечивается следующими классовыми методами:

+ (instancetype)exceptionWithReaded:(SCSize)readed waited:(SCSize)waited stream:(NSString *)stream;
+ (instancetype)exceptionWithReaded:(SCSize)readed waited:(SCSize)waited;

SCL-20028: операция записи не завершена

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

Информация о реально записанных и подлежащих записи символах можно прочитать через свойства класса:

@property (nonatomic, readonly, assign) SCSize writedBytes;
@property (nonatomic, readonly, assign) SCSize waitedBytes;

Для создания экземпляров данной исключительной ситуации предназначены следующие классовые методы:

+ (instancetype)exceptionWithWrited:(SCUInteger)writed waited:(SCUInteger)waited stream:(NSString *)stream;
+ (instancetype)exceptionWithWrited:(SCUInteger)writed waited:(SCUInteger)waited;

SCL-20029: ошибка открытия потока

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

@property (nonatomic, readonly, assign) SCInteger openError;

Создать данную исключительную ситуацию можно с помощью следующих методов класса SCStreamException:

+ (instancetype)exceptionWithOpenError:(SCInteger)error stream:(NSString *)stream;
+ (instancetype)exceptionWithOpenError:(SCInteger)error;

SCL-20030: ошибка чтения данных

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

@property (nonatomic, readonly, assign) SCInteger readError;

За создание данной исключительной ситуации отвечают следующие методы класса SCStreamException:

+ (instancetype)exceptionWithReadError:(SCInteger)error stream:(NSString *)stream;
+ (instancetype)exceptionWithReadError:(SCInteger)error;

SCL-20031: ошибка записи данных

Исключительная ситуация предназначена для обработки ошибок в ходе операций записи данных в поток. Информация в виде полученного от системного или библиотечного вызова кода ошибки сохраняется в свойстве writeError:

@property (nonatomic, readonly, assign) SCInteger writeError;

Для создания экземпляра данной исключительной ситуации класс SCStreamException декларирует следующие классовые методы:

+ (instancetype)exceptionWithWriteError:(SCInteger)error stream:(NSString *)stream;
+ (instancetype)exceptionWithWriteError:(SCInteger)error;

SCL-20032: ошибка класса NSNumber

Исключительная ситуация возникает при обнаружении механизмом потоков неизвестного ей типа числового объекта NSNumber. Данные о встреченном типе NSNumber хранится в свойстве numberType:

@property (nonatomic, readonly, assign) NSString *numberType;

Создание данной исключительной ситуации обеспечивают следующие методы класса SCStreamException:

+ (instancetype)exceptionWithUnsupportedNumberType:(NSString *)type stream:(NSString *)stream;
+ (instancetype)exceptionWithUnsupportedNumberType:(NSString *)type;

SCL-20033: некорректный режим открытия потока

Класс SCFileStream поддерживает определенный набор режимов открытий файловых потоков. При попытке открыть поток с иным режимом генерируется данная исключительная ситуация. Какой именно некорректный режим был передан экземпляру класса, позволяет определить свойство openMode экземпляра класса SCStreamException:

@property (nonatomic, readonly, assign) SCFileStreamOpenMode openMode;

Создать экземпляр данной исключительной ситуации можно с помощью следующих методов класса SCStreamException:

+ (instancetype)exceptionWithOpenMode:(SCFileStreamOpenMode)mode path:(NSString *)path;
+ (instancetype)exceptionWithOpenMode:(SCFileStreamOpenMode)mode;

SCL-20034: пустой путь к файлу потока

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

Создать данную исключительную ситуацию можно путем использования следующих классовых методов:

+ (instancetype)exceptionWithEmptyPath;

SCL-20035: обнаружен конец потока

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

+ (instancetype)exceptionWithEndOfFile:(NSString *)file;
+ (instancetype)exceptionWithEndOfFile;

SCL-20036: некорректное смещение в потоке

Ошибка возникает при попытке позиционировать указатель за пределы потока.

Для работы с данной ошибкой класс SCStreamException определяет следующие свойства:

@property (nonatomic, readonly, assign) SCSystemError seekError;
@property (nonatomic, readonly, assign) NSInteger offset;
@property (nonatomic, readonly, assign) SCFileStreamOffsetWhence whence;

Для создания экземпляров данной исключительной ситуации в классе SCStreamException объявлены следующие классовые методы:

+ (instancetype)exceptionWithSeekError:(SCSystemError)error
whence:(SCFileStreamOffsetWhence)whence
offset:(NSInteger)offset
path:(NSString *)path;
+ (instancetype)exceptionWithSeekError:(SCSystemError)error
whence:(SCFileStreamOffsetWhence)whence
offset:(NSInteger)offset;
+ (instancetype)exceptionWithSeekError:(SCSystemError)error path:(NSString *)path;
+ (instancetype)exceptionWithSeekError:(SCSystemError)error;

SCL-20037: некорректное направление смещения в потоке

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

@property (nonatomic, readonly, assign) SCSystemError seekError;
@property (nonatomic, readonly, assign) SCFileStreamOffsetWhence whence;

Создание экземпляров данной исключительной ситуации обеспечивается следующими классовыми методами, объявленными в классе SCStreamException:

+ (instancetype)exceptionWithWhence:(SCFileStreamOffsetWhence)whence path:(NSString *)path;
+ (instancetype)exceptionWithWhence:(SCFileStreamOffsetWhence)whence;

Класс SCCollectionException

Класс исключительной ситуации SCCollectionException обеспечивает обработку ошибок, которые могут возникнуть при работе с коллекциями библиотеки:


Свойства исключительной ситуации

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

@property (nonatomic, readonly, retain) NSString *collectionName;
@property (nonatomic, readonly, retain) NSString *typeName;
@property (nonatomic, readonly, retain) NSString *unsupported;
@property (nonatomic, readonly, retain) NSString *unknown;
@property (nonatomic, readonly, assign) SCIndex index;
@property (nonatomic, readonly, assign) NSRange range;
@property (nonatomic, readonly, retain) NSIndexSet *indexSet;
@property (nonatomic, readonly, assign) SCULong indexesCount;
@property (nonatomic, readonly, assign) SCULong objectsCount;
@property (nonatomic, readonly, retain) NSString *key;
@property (nonatomic, readonly, assign) SCULong keysCount;

SCL-20040 - неопределенная ошибка коллекции

Ошибка SCL-20040 предназначена для обозначения ошибок коллекции, которые не относятся к уже определенным конкретным исключительным ситуациям. Данный идентификатор введен нами для тех случаев, когда ко всему прочему нет необходимости создавать исключительную ситуацию с отдельным идентификатором.

Для создания исключительных ситуаций с возможностью задать определенные (в том числе и собственные) коды и идентификаторы ошибок могут использоваться следующие методы класса SCCollectionException:

+ (instancetype)exceptionWithName:(NSString *)name reason:(NSString *)reason code:(SCInteger)code eid:(NSString *)eid;
+ (instancetype)exceptionWithReason:(NSString *)reason code:(SCInteger)code eid:(NSString *)eid;

SCL-20041 - исходная коллекция не существует

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

Для создания данной исключительной ситуации класс SCCollectionException декларирует следующие методы:

+ (instancetype)exceptionWithSource;

SCL-20042 - неподдерживаемый тип коллекции

Исключительная ситуация SCL-20042 генерируется если вместе указателя на коллекцию какому-либо методу передается указатель на экземпляр класса другого типа, например, вместо указателя на массив будет передан указатель на строку.

Название класса переданного экземпляра содержится в свойстве typeName:

@property (nonatomic, readonly, retain) NSString *typeName;

Создание экземпляра данной исключительной ситуации обеспечивается следующими методами класса SCCollectionException:

+ (instancetype)exceptionWithUnsupportedType:(NSString *)type;

SCL-20043 - нарушение режима «только для чтения»

Исключительная ситуация SCL-20043: попытка изменения коллекции в режиме только для чтения" SCL-20043" генерируется при попытке внести изменения в коллекцию, находящуюся в режиме "только для чтения".

Класс SCCollectionException декларирует следующие классовые методы для создания данной исключительной ситуации:

+ (instancetype)exceptionWithReadOnlyType:(NSString *)type name:(NSString *)name;
+ (instancetype)exceptionWithReadOnlyType:(NSString *)type;

Обращаем внимание, что параметр type данных методов (а также ряда других) передает методу название типа коллекции, вызвавшей исключительную ситуацию для правильной генерации сообщения об ошибке.


SCL-20044 - добавление нулевого указателя

Ошибка SCL-20044 возникает при попытке добавить в коллекцию нулевой указатель. Для создания данной исключительной ситуации применяются следующие методы класса SCCollectionException:

+ (instancetype)exceptionWithItemType:(NSString *)type name:(NSString *)name;
+ (instancetype)exceptionWithItemType:(NSString *)type;

SCL-20045 - исходный объект не существует

Исключительная ситуация SCL-20045 генерируется в том случае, когда вместо указателя на необходимый для выполнения операции объект передан нулевой указатель.

Создание исключительной ситуации SCL-20045 выполняется следующими методами класса SCCollectionException:

+ (instancetype)exceptionWithObject;

SCL-20046 - неподдерживаемый класс

Если в ходе работы механизма коллекций обнаруживается экземпляр класса, который не соответствует протоколу SCCollectioning, генерируется исключительная ситуация SCL-20046, которая фиксирует название этого класса в свойстве unsupported:

@property (nonatomic, readonly, retain) NSString *unsupported;

Класс SCCollectionException для создания данной исключительной ситуации декларирует следующие классовые методы:

+ (instancetype)exceptionWithUnsupported:(NSString *)cname type:(NSString *)type name:(NSString *)name;
+ (instancetype)exceptionWithUnsupported:(NSString *)cname type:(NSString *)type;

SCL-20047 - неизвестный класс

Когда коллекция в ходе обработки объектов обнаруживает экземпляр класса, который неизвестен системе, генерируется исключительная ситуация SCL-20047, а название такого класса сохраняется в свойстве unknown:

@property (nonatomic, readonly, retain) NSString *unknown;

Создание экземпляров данной исключительной ситуации осуществляется с помощью следующих классовых методов:

+ (instancetype)exceptionWithUnknown:(NSString *)cname type:(NSString *)type name:(NSString *)name;
+ (instancetype)exceptionWithUnknown:(NSString *)cname type:(NSString *)type;

SCL-20048 - объект коллекции не поддерживает сравнивание

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

+ (instancetype)exceptionWithNotComparableType:(NSString *)type name:(NSString *)name;
+ (instancetype)exceptionWithNotComparableType:(NSString *)type;

SCL-20049 - коллекция не поддерживает операции сортировки

Ошибка SCL-20049 возникает при попытке отсортировать коллекцию, которая не поддерживает операции по сортировке своих объектов. За создание экземпляра данной исключительной ситуации отвечают следующие методы класса SCCollectionException:

+ (instancetype)exceptionWithNotSortableType:(NSString *)type name:(NSString *)name;
+ (instancetype)exceptionWithNotSortableType:(NSString *)type;

SCL-20050 - некорректный сортировщик данных

Исключительная ситуация SCL-20050 возникает при попытке выполнить сортировку данных в коллекции с использованием некорректного сортировщика данных. Создание экземпляров данной исключительной ситуации обеспечивают следующие методы класса SCCollectionException:

+ (instancetype)exceptionWithSorterType:(NSString *)type name:(NSString *)name;
+ (instancetype)exceptionWithSorterType:(NSString *)type;

SCL-20052 - некорректный индекс объекта

Если индексируемой коллекции передан индекс, выходящий за ее пределы, генерируется исключительная ситуация SCL-20052, которая хранит обнаруженный ошибочный индекс в свойстве index:

@property (nonatomic, readonly, assign) SCIndex index;

Создать экземпляр данной исключительной ситуации можно с помощью следующих классовых методов:

+ (instancetype)exceptionWithIndex:(SCIndex)index name:(NSString *)name;
+ (instancetype)exceptionWithIndex:(SCIndex)index;

SCL-20053 - некорректный диапазон объектов

При обнаружении факта передачи какому-либо методу коллекции некорректного диапазона объектов генерируется исключительная ситуация SCL-20053. Ошибочный диапазон объектов при этом записывается в свойство range:

@property (nonatomic, readonly, assign) NSRange range;

Создание экземпляра данной исключительной ситуации обеспечивается следующими методами класса SCCollectionException:

+ (instancetype)exceptionWithRange:(NSRange)range name:(NSString *)name;
+ (instancetype)exceptionWithRange:(NSRange)range;

SCL-20054 - некорректный список индексов

Если индексированная коллекция обнаруживает передачу ее методу некорректного множества индексов (пустой указатель на множество или множество, содержащее некорректный индекс), генерируется исключительная ситуация SCL-20054. Вызвавшее ошибку множество индексов доступно через свойство indexSet:

@property (nonatomic, readonly, retain) NSIndexSet *indexSet;

Для создания экземпляров данной исключительной ситуации класс SCCollectionException декларирует следующие классовые методы:

+ (instancetype)exceptionWithIndexSet:(NSIndexSet *)indexSet name:(NSString *)name;
+ (instancetype)exceptionWithIndexSet:(NSIndexSet *)indexSet;

SCL-20055 - несоответствие количества индексов и объектов

Ряд методов индексируемых коллекций оперирует с множествами индексов и списками объектов. При этом количество индексов должно совпадать с количеством объектов. Если коллекция обнаруживает несоответствие между ними, генерируется исключительная ситуация SCL-20055. Сведения об ошибке хранятся в следующих свойствах:

@property (nonatomic, readonly, assign) SCULong indexesCount;
@property (nonatomic, readonly, assign) SCULong objectsCount;

Создание данной исключительной ситуации обеспечивают следующие методы класса SCCollectionException:

+ (instancetype)exceptionWithIndexesCount:(SCULong)indexes objectsCount:(SCULong)objects;

SCL-20056 - ошибка ключа объекта

Если коллекция обнаруживает передачу ей некорректного ключа к объекту (обычно применяются в словарях), то возникает ошибка SCL-20056. Ошибочный ключ хранится в свойстве key экземпляра данной исключительной ситуации:

@property (nonatomic, readonly, retain) NSString *key;

Класс SCCollectionException декларирует следующие методы создания экземпляров данной исключительной ситуации:

+ (instancetype)exceptionWithKey:(NSString *)key name:(NSString *)name;
+ (instancetype)exceptionWithKey:(NSString *)key;

SCL-20057 - несоответствие ключей и объектов

Ошибка SCL-20057 аналогична исключительной ситуации SCL-20055, только вместо количества индексов используется количество ключей. Данные об ошибке хранятся в следующих свойствах экземпляра исключительной ситуации:

@property (nonatomic, readonly, assign) SCULong keysCount;
@property (nonatomic, readonly, assign) SCULong objectsCount;

Создание экземпляров данной исключительной ситуации обеспечивают следующие методы класса SCCollectionException:

+ (instancetype)exceptionWithKeysCount:(SCULong)keys objectsCount:(SCULong)objects;

SCL-20058 - пустое значение

Исключительная SCL-20058 ситуация возникает при попытке назначить ключу пустое значение. Ошибочный ключ хранится в свойстве key:

@property (nonatomic, readonly, retain) NSString *key;

Следующие методы класса SCCollectionException обеспечивают создание экземпляра данной исключительной ситуации:

+ (instancetype)exceptionValueForKey:(NSString *)key name:(NSString *)name;
+ (instancetype)exceptionValueForKey:(NSString *)key;

Класс SCTextException

Класс исключительной ситуации SCTextException обеспечивает обработку ошибок, которые могут возникнуть при работе механизма текстов библиотеки, а именно классов:


Свойства исключительной ситуации

Класс SCTextException объявляет ряд доступных только для чтения свойств:

@property (nonatomic, readonly, retain) NSString *textName;
@property (nonatomic, readonly, retain) NSString *string;
@property (nonatomic, readonly, assign) SCIndex index;
@property (nonatomic, readonly, retain) NSIndexSet *indexSet;
@property (nonatomic, readonly, retain) NSString *unsupported;
@property (nonatomic, readonly, assign) SCULong indexesCount;
@property (nonatomic, readonly, assign) SCULong stringsCount;
@property (nonatomic, readonly, assign) NSRange range;
@property (nonatomic, readonly, assign) NSRange intersected;
@property (nonatomic, readonly, retain) SCStream *stream;

SCL-20060 - неопределенная ошибка текстовых классов

Кроме определенных видов исключительных ситуаций класс SCTextException позволяет создавать исключительные ситуации с дополнительными идентификаторами ошибок, а также исключительную ситуацию неопределенной ошибки текстовых классов SCL-20060:

+ (instancetype)exceptionWithName:(NSString *)name reason:(NSString *)reason code:(SCInteger)code eid:(NSString *)eid;
+ (instancetype)exceptionWithReason:(NSString *)reason code:(SCInteger)code eid:(NSString *)eid;
+ (instancetype)exceptionWithName:(NSString *)name;
+ (instancetype)exception;

SCL-20061 - исходный объект не существует

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

+ (instancetype)sourceExceptionWithName:(NSString *)name;
+ (instancetype)sourceException;

SCL-20062 - некорректный входной поток

Если при попытке загрузки текстового файла из потока будет обнаружена проблема с входным потоком (нулевой указатель на поток, поток не поддерживает операций чтения), текстовый объект генерирует исключительную ситуацию SCL-20062. Указатель на некорректный входной поток доступен через свойство stream:

@property (nonatomic, readonly, retain) SCStream *stream;

За создание экземпляров данной исключительной ситуации отвечают следующие методы класса SCTextException:

+ (instancetype)exceptionWithInputStream:(SCStream *)stream name:(NSString *)name;
+ (instancetype)exceptionWithInputStream:(SCStream *)stream;

SCL-20063 - нарушение режима «только для чтения»

Исключительная ситуация SCL-20063 генерируется при попытке внести изменения в текстовый режим, находящийся в режиме "только для чтения". Создание экземпляров данной исключительной ситуации осуществляется следующими методами класса SCTextException:

+ (instancetype)readOnlyExceptionWithName:(NSString *)name;
+ (instancetype)readOnlyException;

SCL-20064 - добавление нулевой строки

Ошибка SCL-20064 возникает при попытке добавить в текстовый объект нулевую строку, то есть когда текстовому объекту вместо указателя на строку передается нулевой указатель. Класс SCTextException декларирует следующие методы создания экземпляров данной исключительной ситуации:

+ (instancetype)emptyStringExceptionWithName:(NSString *)name;
+ (instancetype)emptyStringException;

SCL-20065 - работа с закрытым потоком

Исключительная ситуация SCL-20065 генерируется при попытке осуществить операцию чтения или записи данных при работе с закрытым потоком. Указатель на данный поток хранится в свойстве stream экземпляра класса:

@property (nonatomic, readonly, retain) SCStream *stream;

Создание экземпляров данной исключительной ситуации осуществляется следующими методами класса SCTextException:

+ (instancetype)exceptionWithClosedStream:(SCStream *)stream name:(NSString *)name;
+ (instancetype)exceptionWithClosedStream:(SCStream *)stream;

SCL-20066 - обнаружен неподдерживаемый класс

Если текстовый объект при обработке данных обнаруживает неподдерживаемый им класс, генерируется исключительная ситуация SCL-20066. Имя неподдерживаемого класса сохраняется в свойстве unsupported:

@property (nonatomic, readonly, retain) NSString *unsupported;

Для создания экземпляров данной исключительной ситуации класс SCTextException декларирует следующие классовые методы:

+ (instancetype)exceptionWithUnsupported:(NSString *)unsupported name:(NSString *)name;
+ (instancetype)exceptionWithUnsupported:(NSString *)unsupported;

SCL-20067 - ошибка чтения данных из потока

Если в ходе загрузки строк из потока возникает ошибка чтения данных, то текстовый объект генерирует исключительную ситуацию SCL-20067, сохраняя в свойстве stream указатель на вызвавший ошибку поток:

@property (nonatomic, readonly, retain) SCStream *stream;

Чтобы создать экземпляр данной исключительной ситуации, необходимо использовать один из следующих методов класса SCTextException:

+ (instancetype)readErrorExceptionWithStream:(SCStream *)stream name:(NSString *)name;
+ (instancetype)readErrorExceptionWithStream:(SCStream *)stream;

SCL-20068 - пустой путь к текстовому файлу

Ошибка SCL-20068 возникает при передаче классу SCTextFile пустого указателя на путь к файлу или указателя на пустую строку в качестве пути к текстовому файлу. За создание экземпляров исключительной ситуации в классе SCTextException отвечают следующие классовые методы:

+ (instancetype)emptyPathExceptionWithName:(NSString *)name;
+ (instancetype)emptyPathException;

SCL-20069 - нарушение уникальности строк

Исключительная ситуация SCL-20069 генерируется классом SCUniqueStrings при обнаружении нарушения уникальности строк, то есть при возникновении ситуации, когда в список добавляется строка, которая в нем уже присутствует. Для обработки данной ошибки класс SCTextException использует следующие свойства и методы:

@property (nonatomic, readonly, retain) NSString *string;
@property (nonatomic, readonly, assign) SCIndex index;

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

+ (instancetype)duplicateExceptionWithName:(NSString *)name string:(NSString *)string index:(SCIndex)index;
+ (instancetype)duplicateExceptionWithString:(NSString *)string index:(SCIndex)index;

SCL-20070 - некорректный сортировщик строк

Если текстовый объект обнаруживает переданный ему некорректный сортировщик строк, генерируется исключительная ситуация SCL-20070, для создания которой класс SCTextException реализует следующие методы:

+ (instancetype)sorterExceptionWithName:(NSString *)name;
+ (instancetype)sorterException;

SCL-20071 - некорректный выходной поток

Если текстовый файл при попытке записи данных обнаруживает нулевой указатель на выходной поток, определяет, что указанный поток не поддерживает операций записи или по иным причинам не может осуществлять запись, генерируется исключительная ситуация SCL-20071. Указатель на вызвавший ошибку поток можно получить из метода stream:

@property (nonatomic, readonly, retain) SCStream *stream;

Создать экземпляр данной исключительной ситуации позволяют следующие классовые методы:

+ (instancetype)exceptionWithOutputStream:(SCStream *)stream name:(NSString *)name;
+ (instancetype)exceptionWithOutputStream:(SCStream *)stream;

SCL-20072 - недопустимый индекс

Исключительная ситуация SCL-20072 генерируется при попытке доступа к строке с некорректным индексом, номер которого можно выяснить из свойства index:

@property (nonatomic, readonly, assign) SCIndex index;

Для создания экземпляра исключительной ситуации могут использоваться следующие классовые методы:

+ (instancetype)exceptionWithIndex:(SCIndex)index name:(NSString *)name;
+ (instancetype)exceptionWithIndex:(SCIndex)index;

SCL-20073 - недопустимый диапазон строк

При обнаружении некорректного диапазона строк текстовый объект генерирует исключительную ситуацию SCL-20073, которая сохраняет обнаруженный диапазон в свойстве range:

@property (nonatomic, readonly, assign) NSRange range;

Создание экземпляров данной исключительной ситуации обеспечивают классовые методы, которые декларируются в классе SCTextException:

+ (instancetype)exceptionWithRange:(NSRange)range name:(NSString *)name;
+ (instancetype)exceptionWithRange:(NSRange)range;

SCL-20074 - некорректный список индексов строк

Некорректный список индексов (список индексов, в котором есть хотя бы один некорректный индекс) вызывает ошибку SCL-20074, сохраняя этот список в свойстве indexSet:

@property (nonatomic, readonly, retain) NSIndexSet *indexSet;

Класс SCTextException декларирует следующие классовые методы создания экземпляров данной исключительной ситуации:

+ (instancetype)exceptionWithIndexSet:(NSIndexSet *)indexSet name:(NSString *)name;
+ (instancetype)exceptionWithIndexSet:(NSIndexSet *)indexSet;

SCL-20075 - несоответствие количества индексов и строк

Некоторые методы текстовых объектов принимают в качестве аргументов списки индексов и списки объектов. Если количество элементов в этих списках не совпадает, то генерируется исключительная ситуация SCL-20075. Класс SCTextException определяет следующие свойства и методы для получения информации о данной ошибке:

@property (nonatomic, readonly, assign) SCULong indexesCount;
@property (nonatomic, readonly, assign) SCULong stringsCount;

Данные классовые методы класса SCTextException позволяют создавать экземпляры данной исключительной ситуации:

+ (instancetype)exceptionWithIndexesCount:(SCULong)icount stringsCount:(SCULong)scount name:(NSString *)name;
+ (instancetype)exceptionWithIndexesCount:(SCULong)icount stringsCount:(SCULong)scount;

SCL-20076 - пересекающиеся диапазоны строк

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

@property (nonatomic, readonly, assign) NSRange range;
@property (nonatomic, readonly, assign) NSRange intersected;

Класс SCTextException реализует следующие классовые методы для создания экземпляров данной исключительной ситуации:

+ (instancetype)exceptionWithRange:(NSRange)range intersected:(NSRange)intersected name:(NSString *)name;
+ (instancetype)exceptionWithRange:(NSRange)range intersected:(NSRange)intersected;

SCL-20077 - ошибка записи данных в поток

Если текстовый объект обнаруживает ошибку, которая возникла в ходе записи данных в поток, генерируется исключительная ситуация SCL-20077. Указатель на вызвавший ошибку поток хранится в свойстве stream:

@property (nonatomic, readonly, retain) SCStream *stream;

Чтобы создать экземпляр данной исключительной ситуации необходимо использовать следующие методы класса SCTextException:

+ (instancetype)writeErrorExceptionWithStream:(SCStream *)stream name:(NSString *)name;
+ (instancetype)writeErrorExceptionWithStream:(SCStream *)stream;

Группирующие классы

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


Класс SCDelegate

Класс SCDelegate объединяет в общую иерархию все классы-обработчики событий (классы делегирования). В текущей версии библиотеки данная иерархия имеет следующий вид:

delegates.png

Класс SCService

Класс SCService создает иерархию вспомогательных классов, которые очень редко используются вне тех или иных механизмов библиотеки. На данный момент иерархия сервисных классов выглядит следующим образом:

services.png

Доступ к информации о библиотеке

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

@property (class, readonly, copy) NSString *version;
@property (class, readonly, copy) NSString *fullVersion;
@property (class, readonly, assign) SCUInteger sclBuild;
@property (class, readonly, copy) NSString *libraryInformation;
@property (class, readonly, copy) NSString *compilationDate;
@property (class, readonly, copy) NSString *compilationDateTime;
@property (class, readonly, copy) NSString *compilationString;
@property (class, readonly, copy) NSString *copyright;

Типы и константы

В данном разделе руководства мы приводим описание неклассовых типов данных, констант и макросов, которые используются остальными компонентами библиотеки:


Стандартные типы данных

Для удобства программирования и обеспечения переносимости программного обеспечения между различными системами, библиотека вводит свои стандартные типы данных, которые определяются в файле SCTypes.h:

Тип данных Описание Размер Примечания
SCBool Логический тип данных 1 байт
SCChar Знаковый символьный тип данных 1 байт
SCByte Знаковый 8-битный целочисленный тип данных 1 байт
SCShort Знаковый 16-битный целочисленный тип данных 2 байта
SCInteger Знаковый 32-битный целочисленный тип данных 4 байта
SCLong Знаковый 64-битный целочисленный тип данных 8 байт
SCSignedLong Знаковый целочисленный тип long 4 или 8 байт
SCUChar Беззнаковый символьный тип данных 1 байт
SCUByte Беззнаковый 8-битный целочисленный тип данных 1 байт
SCUShort Беззнаковый 16-битный целочисленный тип данных 2 байта
SCUInteger Беззнаковый 32-битный целочисленный тип данных 4 байта
SCULong Беззнаковый 64-битный целочисленный тип данных 8 байт
SCUnsignedLong Беззнаковый целочисленный тип unsigned long 4 или 8 байт
SCFloat Тип с плавающей точкой одинарной точности 4 байта
SCDouble Тип с плавающей точкой двойной точности 8 байт
SCVoid Пустой тип данных 1 байт
SCCharString Классическая символьная строка
SCConstString Неизменная классическая символьная строка
SCSelector Тип селектора метода класса
SCClass Классовый тип
SCID Абстрактный объектный тип
SCString Текстровый объект
SCNumber Числовой объект
SCDecimal Десятичный числовой объект
SCDate Дата и время
SCValue Объект для хранения различных значений
SCNull Нулевой объект
SCURL Объект универсального адреса

Специализированные типы данных

Библиотека в файле SCTypes.h объявляет следующие специализированные типы данных:

Тип данных Описание Размер Примечания
SCSize Беззнаковый тип размера данных 4 или 8 байт

Другие типы данных

Файл SCTypes.h содержит объявление следующих дополнительных типов данных:

Тип данных Описание
SCCapacity Перечисляет константы для обозначения разрядности целых чисел (8, 16, 32 и 64 бита)
SCIntegerBase Перечисляет константы для обозначения базы целых чисел

Макросы

Файл SCConstants.h содержит объявление следующих макросов:

#define SCLS( string) NSLocalizedString( string, nil)
#define __abstract__( name) { @throw [SCAbstractMethodException exceptionWithMethod:name]; }

Система определения типов данных

Система определения типов данных разрабатывается с целью обеспечения поддержки различных систем хранения и передачи информации (прежде всего систем управления базами данных) с их различными типами данных. Путем анализа большинства СУБД все многообразие их типов было сведено к ограниченному набору, который объявляется в библиотеке с помощью типа SCDataType (начиная с версии 1.2.5).

Тип SCDataType определяет следующие константы и типы данных:

Константа Описание Тип данных Примечания
SCTypeUnspecified Неопределенный тип данных
SCTypeBool Логический тип данных BOOL
SCTypeChar Знаковый символьный тип данных char
SCTypeByte Знаковый 8-битный целочисленный тип данных SCByte
SCTypeShort Знаковый 16-битный целочисленный тип данных SCShort
SCTypeInteger Знаковый 32-битный целочисленный тип данных SCInteger
SCTypeLong Знаковый 64-битный целочисленный тип данных SCLong
SCTypeSignedLong Знаковый целочисленный тип long SCSignedLong
SCTypeNSInteger Знаковый тип NSInteger NSInteger
SCTypeUChar Беззнаковый символьный тип данных unsigned char
SCTypeUByte Беззнаковый 8-битный целочисленный тип данных SCUByte
SCTypeUShort Беззнаковый 16-битный целочисленный тип данных SCUShort
SCTypeUInteger Беззнаковый 32-битный целочисленный тип данных SCUInteger
SCTypeULong Беззнаковый 64-битный целочисленный тип данных SCULong
SCTypeUnsignedLong Беззнаковый длинный целочисленный тип данных SCUnsignedLong
SCTypeNSUInteger Беззнаковый тип NSUInteger NSUInteger
SCTypeFloat Тип данных с плавающей точкой одинарной точности SCFloat
SCTypeDouble Тип данных с плавающей точкой двойной точности SCDouble
SCTypeVoid Пустой тип данных void
SCTypeCharString Классический символьный тип char *
SCTypeConstString Неизменяемый классический символьный тип const char *
SCTypeSelector Селектор метода класса SEL
SCTypeClass Классовый тип Class
SCTypeObject Объектный тип данных id
SCTypeString Тип символьных данных NSString
SCTypeNumber Тип числовых объектов NSNumber
SCTypeDecimal Тип десятичных числовых объектов NSDecimalNumber
SCTypeDate Тип для хранения даты и времени NSDate
SCTypeArray Массив NSArray
SCTypeDictionary Словарь NSDictionary
SCTypeSet Неупорядоченное множество NSSet
SCTypeData Тип неопределенных двоичных данных NSData
SCTypePointer Тип указателя на данные не реализован
SCTypeBitmap Массив битов (битовая карта) не реализован
SCTypeDataSet Набор данных не реализован
SCTypeCursor Курсор с данными не реализован
SCTypeRowID Тип идентификации записей баз данных не реализован
SCTypeValue Тип для хранения неопределенных данных NSValue
SCTypeNull Тип нулевого (пустого) объекта NSNull
SCTypeURL Тип универсального адреса NSURL
SCTypeConfig Конфигурационный тип не реализован
SCTypeGUID Тип глобальных универсальных идентификаторов не реализован
SCTypeXML Данные XML не реализован

На данный момент не все типы DTDS имеют реализацию в Objective C или нашей библиотеке - постепенно мы будем добавлять новые типы данных из перечисленных выше. Также некоторые типы из стандартных не поддерживают такие механизмы нашей библиотеки, как последовательные файлы и потоки. Такая поддержка также будет добавляться по мере работы над нашей библиотекой.

Дополнительно отметим, что на сегодняшний момент мы не приступали к разработке компонентов, которые будут использовать SDTS в своей работе, однако мы вводим DTDS именно в версии 1.2.5, чтобы в следующих версиях приступить к разработке использующих эту систему механизмов библиотеки.

В состав DTDS также входит тип SCArgumentType, определяющий виды аргументов при работе с различными модулями, например хранимыми процедурами баз данных. Данный тип определяет следующие константы и виды аргументов:

Константа Описание Примечания
SCArgumentUnspecified Неопределенный тип аргумента
SCArgumentReturn Возвращаемое функцией или методом значение
SCArgumentInputOutput Параметр для передачи и возвращения данных
SCArgumentCopy Параметр передается путем копирования данных
SCArgumentReference Параметр передается через ссылку на данные
SCArgumentOneWay Однонаправленный аргумент
SCArgumentInput Параметр для передачи данных в модуль
SCArgumentOutput Параметр для возвращения данных из модуля
SCArgumentConst Неизменяемый параметр

Функции

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


Функции вывода информации

Данные функции обеспечивают форматированный вывод различной информации и являются аналогами стандартным функциям NSLog и NSLogv. Функции были разработаны с двумя целями:

В состав библиотеки входят следующие функции вывода информации:

void SCLog( NSString *format, ...);
void SCLogv( NSString *format, va_list arguments);
void SCLogl();
void SCError( NSString *format, ...);
void SCErrorv( NSString *format, va_list arguments);
void SCErrorl();
void SCPrint( NSString *format, ...);
void SCPrintv( NSString *format, va_list arguments);
void SCPrintError( NSString *format, ...);
void SCPrintErrorv( NSString *format, va_list arguments);