Samond Classes Library 1.2.1-RELEASE build 181
Руководство программиста

Оглавление

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

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


Введение

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

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

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


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

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


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

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


Класс SCObject

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


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

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

- (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 - экземпляры класса не могут сравниваться

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


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

Как было отмечено выше, при работе с потомками класса 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 setBool:NO forKey:@"Verbose"];
[sourceDictionary setInteger:2319 forKey:@"Build"];
[sourceDictionary setObject:[NSDate date] forKey:@"Startup"];
NSMutableDictionary *dictionary = [NSMutableDictionary dictionary];
[sourceDictionary writeToDataDictionary:dictionary];
NSLog( @"%@", dictionary);
2016-06-17 04:19:36.502 libtest[14651:578461] {
Dictionary = {
Build = {
Number = 2319;
"OBJC_ClassName" = NSNumber;
};
Startup = {
Date = "2016-06-17 01:19:36 +0000";
};
System = {
"OBJC_ClassName" = NSString;
String = MacOS;
};
Verbose = {
Number = 0;
"OBJC_ClassName" = NSNumber;
};
};
Name = Configuration;
"OBJC_ClassName" = SCDictionary;
"Read Only" = 0;
}

Метод и свойство 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 setBool:NO forKey:@"Verbose"];
[sourceDictionary setInteger:2319 forKey:@"Build"];
[sourceDictionary setObject:[NSDate date] forKey:@"Startup"];
[sourceDictionary writeToDataDictionaryFile:@"/tmp/data.plist"];

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

sample_03_02.png

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

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

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

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

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

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

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

Потоки

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


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

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, например класс SCFileStream для обработки своих собственных ошибок использует исключительную ситуацию SCFileStreamException.

Приведем пример обработки ошибок потоков через генерацию исключительной ситуации 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, assign, readonly, getter=status) SCStreamStatus status;

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

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


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

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

@property (nonatomic, assign, getter=errorHandling, setter=setErrorHandling:) SCStreamErrorHandling errorHandling;
@property (nonatomic, assign, readonly, getter=status) SCStreamStatus status;
@property (nonatomic, retain, readonly, getter=name) NSString *name;
@property (nonatomic, assign, readonly, getter=opened) BOOL opened;
@property (nonatomic, assign, readonly, getter=eof) BOOL eof;
@property (nonatomic, assign, getter=delegate, setter=setDelegate:) id<SCStreamDelegate> delegate;
@property (nonatomic, assign, readonly, getter=readable) 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;

Кроме данных методов протокола SCStreaming в классах и категориях могут объявляться методы для создания экземпляров классов на основе данных из потоков. Приведем пример таких методов в категории 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 класс SCFileStream генерирует исключительные ситуации SCFileException, которые обрабатывают следующие специфические для файловых потоков ошибки:


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

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


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

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

@property (nonatomic, assign, readonly, getter=openMode) 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 содержит следующие методы позиционирования в файловых потоках:

- (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, assign, readonly, getter=count) SCIndex count;
@property (nonatomic, assign, readonly, getter=empty) BOOL empty;

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

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

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

- (BOOL)readOnly;

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

- (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 обязует программистов реализовать следующие методы:

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

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

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

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

- (NSEnumerator *)objectEnumerator;
- (NSEnumerator *)reverseObjectEnumerator;

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


Протокол 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 не вносят каких-либо изменений в содержимое коллекций. Данному протоколу соответствуют следующие классы библиотеки:

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

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

- (id)firstObject;
- (id)lastObject;
- (id)objectAtIndex:(SCIndex)index;

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

- (SCIndex)indexOfObject:(id<SCCollectioning>)object;
- (SCIndex)indexOfLastObject;

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


Протокол SCMutableIndexedCollection

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

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

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

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

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


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

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

@property (nonatomic, assign, readonly, getter=count) SCIndex count;
@property (nonatomic, assign, readonly, getter=empty) BOOL empty;
@property (nonatomic, retain, getter=name, setter=setName:) NSString *name;
@property (nonatomic, assign, getter=readOnly, setter=setReadOnly:) BOOL readOnly;
@property (nonatomic, assign, getter=delegate, setter=setDelegate:) id<SCCollectionDelegate> delegate;
@property (nonatomic, retain, readonly, getter=typeName) 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)isEqualToContentsOfCollection:(id<SCCollection>)collection;
- (BOOL)isEqual:(id)object;

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

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

- (NSEnumerator *)objectEnumerator;
- (NSEnumerator *)reverseObjectEnumerator;
- (void)enumerateWithDelegate:(id<SCCollectionDelegate>)delegate;
- (void)enumerate;
- (void)reverseEnumerateWithDelegate:(id<SCCollectionDelegate>)delegate;
- (void)reverseEnumerate;

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

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

- (SCArray *)array;
- (SCSet *)set;
- (SCOrderedSet *)orderedSet;
- (SCDictionary *)dictionary;
- (SCStack *)stack;
- (SCQueue *)queue;
- (SCUnidirectionalList *)unidirectionalList;
- (SCBidirectionalList *)bidirectionalList;
- (NSArray *)foundationArray;
- (NSSet *)foundationSet;
- (NSOrderedSet *)foundationOrderedSet;
- (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 объявляет методы, позволяющие программистам определить, к какому типу коллекции относится конкретный экземпляр класса:

- (BOOL)isCollection;
- (BOOL)isLibraryCollection;
- (BOOL)isFoundationCollection;
- (BOOL)isArray;
- (BOOL)isLibraryArray;
- (BOOL)isFoundationArray;
- (BOOL)isSet;
- (BOOL)isLibrarySet;
- (BOOL)isFoundationSet;
- (BOOL)isOrderedSet;
- (BOOL)isLibraryOrderedSet;
- (BOOL)isFoundationOrderedSet;
- (BOOL)isDictionary;
- (BOOL)isLibraryDictionary;
- (BOOL)isFoundationDictionary;
- (BOOL)isStack;
- (BOOL)isQueue;
- (BOOL)isList;
- (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)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;
- (BOOL)isEqualToContentsOfArray:(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]);
NSLog( @"==================================");
NSLog( @"[array isEqualToContentsOfArray:source] = %d", [array isEqualToContentsOfArray:source]);
NSLog( @"[array isEqualToContentsOfArray:sample] = %d", [array isEqualToContentsOfArray:sample]);
2016-07-25 01:36:51.081 libtest[11081:1745880] [array isEqualToArray:source] = 0
2016-07-25 01:36:51.081 libtest[11081:1745880] [array isEqualToArray:sample] = 0
2016-07-25 01:36:51.081 libtest[11081:1745880] ==================================
2016-07-25 01:36:51.081 libtest[11081:1745880] [array isEqualToContentsOfArray:source] = 1
2016-07-25 01:36:51.081 libtest[11081:1745880] [array isEqualToContentsOfArray:sample] = 0

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

Массивы, как и любые коллекции с индексируемым доступом к объектам, могут обеспечивать различные виды сортировки своего содержимого. Класс 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;
- (SCArray *)ascendingSortedArray;
- (SCArray *)descendingSortedArray;
- (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;

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

Для реализации механизма индексного доступа к объектам класс 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;

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

Для копирования и перемещения объектов в массиве класс 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 объявляет следующие методы для доступа к объектам массива:

- (id)firstObject;
- (id)lastObject;
- (id)objectAtIndex:(SCIndex)index;
- (SCArray *)objectsAtIndexes:(NSIndexSet *)indexes;
- (SCArray *)objectsInRange:(NSRange)range;

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

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

- (SCIndex)indexOfObject:(id<SCCollectioning>)object;
- (SCIndex)indexOfObject:(id<SCCollectioning>)object inRange:(NSRange)range;
- (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;

Класс 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)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)init;

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

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

- (void)setSet:(SCSet *)set;
SCSet *set = [SCSet setWithObjects:@"System", @"Information", @"String", nil];
NSLog( @"%@", set);
SCSet *source = [SCSet setWithObjects:@"Line 00", @"Line 01", @"Line 02", nil];
[set setSet:source];
NSLog( @"%@", set);
2016-07-25 16:54:30.830 libtest[1242:50070] Set count=3: {(
"String",
"System",
"Information"
)}
2016-07-25 16:54:30.830 libtest[1242:50070] Set count=3: {(
"Line 00",
"Line 01",
"Line 02"
)}

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

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

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

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

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

@property (nonatomic, retain, readonly, getter=allObjects) SCArray *allObjects;
@property (nonatomic, retain, readonly, getter=anyObject) id anyObject;

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

Неупорядоченные множества на базе класса 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;

Для создания упорядоченных множеств класс 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;

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

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

- (BOOL)isSubsetOfOrderedSet:(id<SCCollection>)orderedSet;
- (BOOL)isSubsetOfSet:(id<SCCollection>)set;
- (BOOL)intersectsOrderedSet:(id<SCCollection>)orderedSet;
- (BOOL)intersectsSet:(id<SCCollection>)set;
- (BOOL)isEqualToOrderedSet:(id<SCCollection>)orderedSet;
- (BOOL)isEqualToContentsOfOrderedSet:(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;
- (SCOrderedSet *)ascendingSortedOrderedSet;
- (SCOrderedSet *)descendingSortedOrderedSet;
- (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;

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

Для реализации механизма индексного доступа к объектам класс 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;

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

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

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

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

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

- (SCArray *)allObjects;
- (id)firstObject;
- (id)lastObject;
- (id)objectAtIndex:(SCIndex)index;
- (SCArray *)objectsAtIndexes:(NSIndexSet *)indexes;
- (SCOrderedSet *)reversedOrderedSet;

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

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

- (SCIndex)indexOfObject:(id<SCCollectioning>)object;
- (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;

Создание словарей осуществляется следующими классовыми методами класса 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;
- (BOOL)isEqualToContentsOfDictionary:(SCDictionary *)dictionary;

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

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

- (void)setObject:(id<SCCollectioning>)object forKey:(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, ...;

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

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

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

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

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

- (SCArray *)allKeys;
- (SCArray *)allValues;
- (SCArray *)allKeysForObject:(id<SCCollectioning>)object;

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

- (id)objectForKey:(NSString *)key;
[dictionary setObject:@"MacOS" forKey:@"System"];
[dictionary setObject:@"10.11.6" forKey:@"Version"];
[dictionary setObject:@"samond@mac.com" forKey:@"Contact"];
NSLog( @"%@", [dictionary objectForKey:@"System"]);
NSLog( @"%@", [dictionary objectForKey:@"OS"]);
2016-08-04 13:16:01.573 libtest[20308:3766321] MacOS
2016-08-04 13:16:01.573 libtest[20308:3766321] (null)

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

- (id)valueForKey:(NSString *)key;
[dictionary setObject:@"MacOS" forKey:@"System"];
[dictionary setObject:@"10.11.6" forKey:@"Version"];
[dictionary setObject:@"samond@mac.com" forKey:@"Contact"];
NSLog( @"%@", [dictionary valueForKey:@"System"]);
NSLog( @"%@", [dictionary valueForKey:@"OS"]);
2016-08-04 13:24:52.514 libtest[20402:3772023] MacOS
2016-08-04 13:24:52.514 libtest[20402:3772023] (null)

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

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

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

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

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

- (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;

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

+ (instancetype)stackWithName:(NSString *)name;
+ (instancetype)stackWithObject:(id<SCCollectioning>)object;
+ (instancetype)stackWithObjects:(id<SCCollectioning>)object, ...;
+ (instancetype)stackWithCollection:(id<SCCollection>)collection;
+ (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)initWithStack:(SCStack *)stack;
- (instancetype)init;

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

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

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

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

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

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

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

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

- (void)pushObject:(id<SCCollectioning>)object;
- (void)pushObjects:(id<SCCollectioning>)object, ...;
- (void)pushCollection:(id<SCCollection>)collection;

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

Для извлечения объектов из стека класс 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:

- (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;

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

+ (instancetype)queueWithName:(NSString *)name;
+ (instancetype)queueWithObject:(id<SCCollectioning>)object;
+ (instancetype)queueWithObjects:(id<SCCollectioning>)object, ...;
+ (instancetype)queueWithCollection:(id<SCCollection>)collection;
+ (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)initWithQueue:(SCQueue *)queue;
- (instancetype)init;

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

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

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

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

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

- (BOOL)isEqualToQueue:(SCQueue *)queue;
- (BOOL)isEqualToContentsOfQueue:(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 объявляет следующие методы:

- (id)firstObject;

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

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

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


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

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

+ (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)listWithName:(NSString *)name;
+ (instancetype)listWithObject:(id<SCCollectioning>)object;
+ (instancetype)listWithObjects:(id<SCCollectioning>)object, ...;
+ (instancetype)listWithCollection:(id<SCCollection>)collection;
+ (instancetype)listWithList:(SCList *)list;
+ (instancetype)list;

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

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

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

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

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

- (id)currentObject;
- (id)firstObject;

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

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

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

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

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

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

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

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

- (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 объявляет следующие методы:

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

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

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

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

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

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

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

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

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

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

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

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

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

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


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

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

+ (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)listWithName:(NSString *)name;
+ (instancetype)listWithObject:(id<SCCollectioning>)object;
+ (instancetype)listWithObjects:(id<SCCollectioning>)object, ...;
+ (instancetype)listWithCollection:(id<SCCollection>)collection;
+ (instancetype)listWithList:(SCList *)list;
+ (instancetype)list;

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

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

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

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

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

- (id)lastObject;

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


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

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

- (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)stringsWithName:(NSString *)name;
+ (instancetype)stringsWithString:(NSString *)string;
+ (instancetype)stringsWithCollection:(id<SCCollection>)collection;
+ (instancetype)stringsWithStrings:(SCStrings *)strings;
+ (instancetype)strings;

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

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

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

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

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

@property (nonatomic, retain, getter=name, setter=setName:) NSString *name;
@property (nonatomic, assign, readonly, getter=count) SCIndex count;
@property (nonatomic, assign, getter=readOnly, setter=setReadOnly:) BOOL readOnly;
@property (nonatomic, assign, readonly, getter=empty) BOOL empty;
@property (nonatomic, assign, readonly, getter=modified) BOOL modified;
@property (nonatomic, assign, getter=caseInsensitive, setter=setCaseInsensitive:) BOOL caseInsensitive;
@property (nonatomic, retain, getter=delegate, setter=setDelegate:) id<SCTextDelegate> delegate;

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

- (NSString *)name;
- (SCULong)count;
- (BOOL)readOnly;
- (BOOL)empty;
- (BOOL)modified;
- (BOOL)caseInsensitive;
- (id)delegate;

Также класс декларирует методы установки значений свойств экземпляра класса SCStrings:

- (void)setName:(NSString *)name;
- (void)setReadOnly:(BOOL)readOnly;
- (void)setCaseInsensitive:(BOOL)caseInsensitive;
- (void)setDelegate:(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 предоставляет следующие свойства и методы:

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

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

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

@property (nonatomic, retain, readonly, getter=array) SCArray *array;
@property (nonatomic, retain, readonly, getter=foundationArray) NSArray *foundationArray;
- (SCArray *)array;
- (NSArray *)foundationArray;

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

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

@property (nonatomic, retain, readonly, getter=sortedStrings) SCStrings *sortedStrings;
- (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;
- (SCStrings *)ascendingSortedStrings;
- (SCStrings *)descendingSortedStrings;
- (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;

При работе данных методов осуществляется вызов событий 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 является не просто контейнером для хранения различных строк, но и предоставляет достаточно мощные средства для построчной обработки своего содержимого. К этим средствам относятся такие методы класса, как:

- (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, retain, readonly, getter=reversedStrings) SCStrings *reversedStrings;
- (void)reverse;
- (SCStrings *)reversedStrings;

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

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

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

Поиск строк

Класс 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, assign, readonly, getter=indexOfLastString) 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, assign, getter=strongMode, setter=setStrongMode:) BOOL strongMode;
- (BOOL)strongMode;
- (void)setStrongMode:(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;

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

+ (instancetype)uniqueStringsWithName:(NSString *)name;
+ (instancetype)uniqueStringsWithString:(NSString *)string;
+ (instancetype)uniqueStringsWithCollection:(id<SCCollection>)collection;
+ (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, retain, readonly, getter=strings) SCStrings *strings;
@property (nonatomic, retain, readonly, getter=orderedSet) SCOrderedSet *orderedSet;
@property (nonatomic, retain, readonly, getter=foundationOrderedSet) NSOrderedSet *foundationOrderedSet;
- (SCStrings *)strings;
- (SCOrderedSet *)orderedSet;
- (NSOrderedSet *)foundationOrderedSet;

Тексты

Класс 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;

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

+ (instancetype)textWithName:(NSString *)name;
+ (instancetype)textWithString:(NSString *)string;
+ (instancetype)textWithStrings:(SCStrings *)strings;
+ (instancetype)textWithCollection:(id<SCCollection>)collection;
+ (instancetype)textWithText:(SCText *)text;
+ (instancetype)text;

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

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

- (instancetype)initWithText:(SCText *)text;

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

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

- (void)setText:(SCText *)text;

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

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

- (BOOL)isEqualToText:(SCText *)text;

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

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

@property (nonatomic, retain, readonly, getter=strings) SCStrings *strings;
@property (nonatomic, retain, readonly, getter=uniqueStrings) SCUniqueStrings *uniqueStrings;
- (SCStrings *)strings;
- (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, retain, readonly, getter=path) NSString *path;
@property (nonatomic, assign, readonly, getter=modified) 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;

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

+ (instancetype)textFileWithName:(NSString *)name;
+ (instancetype)textFileWithString:(NSString *)string;
+ (instancetype)textFileWithStrings:(SCStrings *)strings;
+ (instancetype)textFileWithCollection:(id<SCCollection>)collection;
+ (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 объявляет следующие методы преобразования текстовых файлов в экземпляры других классов:

- (SCStrings *)strings;
- (SCUniqueStrings *)uniqueStrings;
- (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, SCFileStreamException и SCSystemException.

SCTextErrorInputStream = -20062, // Некорректный входной поток
SCTextErrorClosedStream = -20065, // Работа с закрытым потоком
SCTextErrorRead = -20067, // Ошибка чтения данных из потока
SCTextErrorEmptyPath = -20068, // Пустой путь к текстовому файлу
SCTextErrorOutputStream = -20071, // Некорректный выходной поток
SCTextErrorWrite = -20077, // Ошибка записи данных в поток

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

Протокол делегирования SCTextDelegate декларирует методы, которые можно разделить на ряд функциональных групп:

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


Текстовые индексы

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

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

@property (nonatomic, assign, getter=line, setter=setLine:) SCULong line;
@property (nonatomic, assign, getter=character, setter=setCharacter:) SCULong character;
- (SCULong)line;
- (SCULong)character;
- (void)setLine:(SCULong)line;
- (void)setCharacter:(SCULong)character;

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

+ (instancetype)textIndexWithLine:(SCULong)line character:(SCULong)character;
+ (instancetype)textIndexWithTextIndex:(SCTextIndex *)textIndex;
+ (instancetype)textIndex;

Расширения класса 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;

Категория 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 большим диапазоном методов разделения строк на части и замены строк и подстрок. Для удобства описания методов глава разделяется на ряд параграфов в соответствии с назначением методов.


Отбрасывание частей строк

- (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;
- (SCArray *)indexesOfSubstring:(NSString *)substring caseInsensitive:(BOOL)caseInsensitive;
- (SCArray *)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, retain, readonly, getter=normalizedString) NSString *normalizedString;
@property (nonatomic, assign, readonly, getter=wordsCount) SCIndex wordsCount;
@property (nonatomic, retain, readonly, getter=firstWord) NSString *firstWord;
@property (nonatomic, retain, readonly, getter=lastWord) NSString *lastWord;
@property (nonatomic, retain, readonly, getter=endOfString) NSString *endOfString;
- (NSString *)normalizedString;
- (SCIndex)wordsCount;
- (NSString *)word:(SCIndex)word;
- (NSString *)firstWord;
- (NSString *)lastWord;
- (NSString *)endOfString;

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

Существующие в классе 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) объявляет ряд методов, позволяющих определить, является ли та или иная строка символьным представлением числа в различных форматах:

- (BOOL)isBinaryString;
- (BOOL)isOctalString;
- (BOOL)isDecimalString;
- (BOOL)isHexadecimalString;
- (BOOL)isBooleanString;
- (BOOL)isFloatString;
- (BOOL)isDoubleString;

Преобразование строк в числовой формат

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

@property (nonatomic, assign, readonly, getter=binaryValue) SCULong binaryValue;
@property (nonatomic, assign, readonly, getter=octalValue) SCULong octalValue;
@property (nonatomic, assign, readonly, getter=decimalValue) SCULong decimalValue;
@property (nonatomic, assign, readonly, getter=hexadecimalValue) SCULong hexadecimalValue;
@property (nonatomic, assign, readonly, getter=booleanValue) BOOL booleanValue;
- (SCULong)binaryValue;
- (SCULong)octalValue;
- (SCULong)decimalValue;
- (SCULong)hexadecimalValue;
- (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, retain, readonly, getter=reversedString) NSString *reversedString;
- (NSString *)reversedString;
+ (instancetype)stringWithReversedString:(NSString *)string;
- (instancetype)initWithReversedString:(NSString *)string;

Другие методы

Кроме вышеперечисленных свойств и методов категория NSString(SCString) декларирует следующие методы и свойства, которые нельзя отнести к какой-либо конкретной группе:

@property (nonatomic, assign, readonly, getter=empty) BOOL empty;
- (BOOL)empty;
- (NSString *)stringWithUpperFirstLetter;

Расширения стандартных классов

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


Расширение класса NSObject

Базовый стандартный класс NSObject реализует стандартные для всех классов возможности. Именно поэтому нами была создана категория NSObject(SCObject), через которую мы добавляем поддержку механизмов нашей библиотеки сразу во все классы, прежде всего поддержку протоколов SCCoding, SCDictionaring, SCStreaming и SCCollectioning.

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


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

Для обеспечения поддержки последовательных файлов путем реализации протокола 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;

Расширение класса 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;

Категория 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, assign, readonly, getter=byteValue) SCByte byteValue;
@property (nonatomic, assign, readonly, getter=unsignedByteValue) SCUByte unsignedByteValue;
@property (nonatomic, assign, readonly, getter=unicharValue) unichar unicharValue;

Кроме вышеперечисленных свойств в категории NSNumber(SCNumber) объявлены свойства для получения различных текстовых представлений числовых объектов:

@property (nonatomic, assign, readonly, getter=binaryString) NSString *binaryString;
@property (nonatomic, retain, readonly, getter=octalString) NSString *octalString;
@property (nonatomic, retain, readonly, getter=decimalString) NSString *decimalString;
@property (nonatomic, retain, readonly, getter=string) NSString *string;
@property (nonatomic, retain, readonly, getter=hexadecimalString) NSString *hexadecimalString;
@property (nonatomic, retain, readonly, getter=boolString) NSString *boolString;
@property (nonatomic, retain, readonly, getter=floatString) NSString *floatString;
@property (nonatomic, retain, readonly, getter=doubleString) NSString *doubleString;

Определение типов числовых объектов

Числовой объект NSNumber может содержать данные различного типа, который определяется при создании экземпляра класса. Для получения информации о типе числового объекта категория NSNumber(SCNumber) используется метод 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;

Расширение класса 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;

Расширение класса 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;

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

+ (instancetype)arrayWithCollection:(id<SCCollection>)collection;

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

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

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

Реализация протокола SCCollection

Наиболее востребованными методами протокола SCCollection в классе NSArray являются следующие методы и свойства категории NSArray(SCArray):

@property (nonatomic, assign, readonly, getter=empty) BOOL empty;
@property (nonatomic, assign, readonly, getter=readOnly) BOOL readOnly;
- (BOOL)empty;
- (BOOL)readOnly;

Также для реализации протокола SCCollection категория NSArray(SCArray) реализует методы определения типов коллекций:

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

Для экземпляров класса NSArray и его потомка NSMutableArray значение YES возвращают методы:

Остальные методы из этого списка возвращают значение NO.


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

Категория NSArray(SCArray) реализует следующие методы поиска объектов из протокола SCCollection:

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

Преобразование массивов

В соответствии с протоколом SCCollection категория NSArray(SCArray) реализует свойства и методы преобразования массивов типа NSArray в другие виды поддерживаемых библиотекой коллекций:

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

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

Согласно протоколу SCCollection категория NSArray(SCArray) реализует следующие свойства и методы сортировки содержимого массива:

@property (nonatomic, retain, readonly, getter=sortedArray) NSArray *sortedArray;
- (NSArray *)ascendingSortedArrayWithSorter:(id<SCSorter>)sorter;
- (NSArray *)descendingSortedArrayWithSorter:(id<SCSorter>)sorter;
- (NSArray *)sortedArrayWithSorter:(id<SCSorter>)sorter;
- (NSArray *)ascendingSortedArray;
- (NSArray *)descendingSortedArray;
- (NSArray *)sortedArray;

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

+ (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;

Расширение класса 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;

Удаление элементов

Полную поддержку средств удаления объектов протокола 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)setWithCollection:(id<SCCollection>)collection;

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

Категория объявляет дополнительные методы инициализации неупорядоченных множеств:

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

Реализация протокола SCCollection

В рамках реализации протокола SCCollection категория NSSet(SCSet) декларирует следующие свойства и методы:

@property (nonatomic, assign, readonly, getter=empty) BOOL empty;
@property (nonatomic, assign, readonly, getter=readOnly) BOOL readOnly;
- (BOOL)empty;
- (BOOL)readOnly;

Также категория реализует методы протокола SCCollection, служащие для определения принадлежности экземпляра класса к тому или иному типу коллекций:

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

Для стандартных упорядоченных множеств значение 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, retain, readonly, getter=array) SCArray *array;
@property (nonatomic, retain, readonly, getter=set) SCSet *set;
@property (nonatomic, retain, readonly, getter=orderedSet) SCOrderedSet *orderedSet;
@property (nonatomic, retain, readonly, getter=dictionary) SCDictionary *dictionary;
@property (nonatomic, retain, readonly, getter=stack) SCStack *stack;
@property (nonatomic, retain, readonly, getter=queue) SCQueue *queue;
@property (nonatomic, retain, readonly, getter=unidirectionalList) SCUnidirectionalList *unidirectionalList;
@property (nonatomic, retain, readonly, getter=bidirectionalList) SCBidirectionalList *bidirectionalList;
@property (nonatomic, retain, readonly, getter=foundationArray) NSArray *foundationArray;
@property (nonatomic, retain, readonly, getter=foundationSet) NSSet *foundationSet;
@property (nonatomic, retain, readonly, getter=foundationOrderedSet) NSOrderedSet *foundationOrderedSet;
@property (nonatomic, retain, readonly, getter=foundationDictionary) NSDictionary *foundationDictionary;
- (SCArray *)array;
- (SCSet *)set;
- (SCOrderedSet *)orderedSet;
- (SCDictionary *)dictionary;
- (SCStack *)stack;
- (SCQueue *)queue;
- (SCUnidirectionalList *)unidirectionalList;
- (SCBidirectionalList *)bidirectionalList;
- (NSArray *)foundationArray;
- (NSSet *)foundationSet;
- (NSOrderedSet *)foundationOrderedSet;
- (NSDictionary *)foundationDictionary;

Расширение класса 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)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)orderedSetWithCollection:(id<SCCollection>)collection;

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

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

Реализация протокола SCCollection

Категория NSOrderedSet(SCOrderedSet) декларирует следующие свойства и методы протокола SCCollection:

@property (nonatomic, assign, readonly, getter=empty) BOOL empty;
@property (nonatomic, assign, readonly, getter=readOnly) BOOL readOnly;
- (BOOL)empty;
- (BOOL)readOnly;

Следующие методы категории NSOrderedSet(SCOrderedSet) и протокола SCCollection определяют тип коллекции, к которой относится экземпляр класса:

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

Значение YES возвращают методы isCollection, isFoundationCollection, isOrderedSet и isFoundationOrderedSet.


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

Категория NSOrderedSet(SCOrderedSet) реализует следующие методы протокола SCCollection:

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

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

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

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

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

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

@property (nonatomic, retain, readonly, getter=sortedOrderedSet) NSOrderedSet *sortedOrderedSet;
- (NSOrderedSet *)ascendingSortedOrderedSetWithSorter:(id<SCSorter>)sorter;
- (NSOrderedSet *)descendingSortedOrderedSetWithSorter:(id<SCSorter>)sorter;
- (NSOrderedSet *)sortedOrderedSetWithSorter:(id<SCSorter>)sorter;
- (NSOrderedSet *)ascendingSortedOrderedSet;
- (NSOrderedSet *)descendingSortedOrderedSet;
- (NSOrderedSet *)sortedOrderedSet;

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

+ (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) также реализует следующие методы, которые мы затрудняемся отнести к той или иной группе:

@property (nonatomic, retain, readonly, getter=allObjects) NSArray* allObjects;
- (NSArray *)allObjects;

Расширение класса NSMutableOrderedSet

Категория NSMutableOrderedSet(SCMutableOrderedSet) дополняет стандартный класс изменяемых упорядоченных множеств функциональностью протоколов SCMutableCollection и SCMutableIndexedCollection.


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

Для реализации методов копирования коллекций протокола SCMutableCollection категория NSMutableOrderedSet(SCMutableOrderedSet) реализует эти методы в классе NSMutableOrderedSet:

- (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;

Удаление элементов

Категория реализует следующие методы удаления объектов протокола 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)dictionaryWithCollection:(id<SCCollection>)collection;

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

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

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

Реализация протокола SCCollection

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

@property (nonatomic, assign, readonly, getter=empty) BOOL empty;
@property (nonatomic, assign, readonly, getter=readOnly) BOOL readOnly;
- (BOOL)empty;
- (BOOL)readOnly;

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

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

Для экземпляров классов 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;

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

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

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

Расширение класса 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;

Удаление элементов

Для удаления объектов категория 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;

Классы и категории macOS

Предупреждения
Описанные в данном разделе классы и категории поддерживаются только в операционной системе macOS и ограниченно на платформе GNUstep.

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


Категория NSButton(SCButton)

Категория NSButton(SCButton) добавляет в стандартный класс NSButton следующее свойство:

@property (nonatomic, getter=stateWithBool, setter=setStateWithBool:) BOOL boolState;

Данное свойство позволяет переключать состояние интерфейсной кнопки с помощью логического значения:


Категория NSAlert(SCAlert)

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

sample_10_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

Класс SCException

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


Коды и идентификаторы ошибок

Каждая ошибка в библиотеке имеет свои собственные код и идентификатор.

Код ошибки - отрицательное число, начиная от значения -20000 и ниже. Такой выбор связан с кодами ошибок, которые СУБД ORACLE выделяет для пользовательских ошибок. Собственно сама система формирования кодов и идентификаторов ошибок взята нами из ORACLE.

Для получения идентификатора ошибки используется свойство code:

@property (assign, readonly, getter=code) SCInteger code;
- (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 (retain, readonly, getter=eid) NSString *eid;
- (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, retain, readonly, getter=methodName) NSString *methodName;
- (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;
- (SCSystemError)error;
- (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 (retain, readonly, getter=unsupportedType) NSString *unsupportedType;
- (NSString *)unsupportedType;

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

+ (instancetype)exceptionWithUnsupportedType:(NSString *)type;

Класс SCStreamException

Класс исключительной ситуации SCStreamException обеспечивает обработку ошибок механизма потоков (кроме ошибок файловых потоков, которые обрабатывает класс исключительной ситуации SCFileStreamException).


Свойства исключительной ситуации

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

@property (nonatomic, retain, readonly, getter=streamName) NSString *streamName;
@property (retain, readonly, getter=unknown) NSString *unknown;
@property (nonatomic, retain, readonly, getter=unexpected) NSString *unexpected;
@property (nonatomic, retain, readonly, getter=expected) NSString *expected;
@property (retain, readonly, getter=unsupported) NSString *unsupported;
@property (nonatomic, assign, readonly, getter=readedBytes) SCUInteger readedBytes;
@property (nonatomic, assign, readonly, getter=writedBytes) SCUInteger writedBytes;
@property (nonatomic, assign, readonly, getter=waitedBytes) SCUInteger waitedBytes;
@property (nonatomic, assign, readonly, getter=openError) SCInteger openError;
@property (nonatomic, assign, readonly, getter=readError) SCInteger readError;
@property (nonatomic, assign, readonly, getter=writeError) SCInteger writeError;
@property (assign, readonly, getter=numberType) NSString *numberType;
- (NSString *)streamName;
- (NSString *)unknown;
- (NSString *)unexpected;
- (NSString *)expected;
- (NSString *)unsupported;
- (SCUInteger)readedBytes;
- (SCUInteger)writedBytes;
- (SCUInteger)waitedBytes;
- (SCInteger)openError;
- (SCInteger)readError;
- (SCInteger)writeError;
- (NSString *)numberType;

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 (retain, readonly, getter=unknown) NSString *unknown;
- (NSString *)unknown;

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

+ (instancetype)exceptionWithUnknown:(NSString *)name stream:(NSString *)stream;
+ (instancetype)exceptionWithUnknown:(NSString *)name;

SCL-20025: обнаружен экземпляр класса неожиданного типа

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

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

@property (nonatomic, retain, readonly, getter=unexpected) NSString *unexpected;
@property (nonatomic, retain, readonly, getter=expected) NSString *expected;
- (NSString *)unexpected;
- (NSString *)expected;

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

+ (instancetype)exceptionWithUnexpected:(NSString *)unexpected expected:(NSString *)expected stream:(NSString *)stream;
+ (instancetype)exceptionWithUnexpected:(NSString *)unexpected expected:(NSString *)expected;

SCL-20026: обнаружен неподдерживаемый класс

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

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

@property (retain, readonly, getter=unsupported) NSString *unsupported;
- (NSString *)unsupported;

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

+ (instancetype)exceptionWithUnsupported:(NSString *)name stream:(NSString *)stream;
+ (instancetype)exceptionWithUnsupported:(NSString *)name;

SCL-20027: операция чтения не завершена

Ошибка возникает в том случае, если из потока было загружено меньше символов, чем было запрошено.

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

@property (nonatomic, assign, readonly, getter=readedBytes) SCSize readedBytes;
@property (nonatomic, assign, readonly, getter=waitedBytes) SCSize waitedBytes;
- (SCSize)readedBytes;
- (SCSize)waitedBytes;

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

+ (instancetype)exceptionWithReaded:(SCSize)readed waited:(SCSize)waited stream:(NSString *)stream;
+ (instancetype)exceptionWithReaded:(SCSize)readed waited:(SCSize)waited;

SCL-20028: операция записи не завершена

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

Информация о реально записанных и подлежащих записи символах можно прочитать через свойства и методы класса:

@property (nonatomic, assign, readonly, getter=writedBytes) SCSize writedBytes;
@property (nonatomic, assign, readonly, getter=waitedBytes) SCSize waitedBytes;
- (SCSize)writedBytes;
- (SCSize)waitedBytes;

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

+ (instancetype)exceptionWithWrited:(SCUInteger)writed waited:(SCUInteger)waited stream:(NSString *)stream;
+ (instancetype)exceptionWithWrited:(SCUInteger)writed waited:(SCUInteger)waited;

SCL-20029: ошибка открытия потока

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

@property (nonatomic, assign, readonly, getter=openError) SCInteger openError;
- (SCInteger)openError;

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

+ (instancetype)exceptionWithOpenError:(SCInteger)error stream:(NSString *)stream;
+ (instancetype)exceptionWithOpenError:(SCInteger)error;

SCL-20030: ошибка чтения данных

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

@property (nonatomic, assign, readonly, getter=readError) SCInteger readError;
- (SCInteger)readError;

За создание данной исключительной ситуации отвечают следующие методы класса SCStreamException:

+ (instancetype)exceptionWithReadError:(SCInteger)error stream:(NSString *)stream;
+ (instancetype)exceptionWithReadError:(SCInteger)error;

SCL-20031: ошибка записи данных

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

@property (nonatomic, assign, readonly, getter=writeError) SCInteger writeError;
- (SCInteger)writeError;

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

+ (instancetype)exceptionWithWriteError:(SCInteger)error stream:(NSString *)stream;
+ (instancetype)exceptionWithWriteError:(SCInteger)error;

SCL-20032: ошибка класса NSNumber

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

@property (assign, readonly, getter=numberType) NSString *numberType;
- (NSString *)numberType;

Создание данной исключительной ситуации обеспечивают следующие методы класса SCStreamException:

+ (instancetype)exceptionWithUnsupportedNumberType:(NSString *)type stream:(NSString *)stream;
+ (instancetype)exceptionWithUnsupportedNumberType:(NSString *)type;

Класс SCFileStreamException

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


Свойства исключительной ситуации

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

@property (assign, readonly, getter=openMode) SCFileStreamOpenMode openMode;
@property (assign, readonly, getter=seekError) SCSystemError seekError;
@property (assign, readonly, getter=offset) SCLong offset;
@property (assign, readonly, getter=whence) SCFileStreamOffsetWhence whence;
- (SCSystemError)seekError;
- (SCLong)offset;

SCL-20033: некорректный режим открытия файла потока

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

@property (assign, readonly, getter=openMode) SCFileStreamOpenMode openMode;

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

+ (instancetype)exceptionWithOpenMode:(SCFileStreamOpenMode)mode path:(NSString *)path;
+ (instancetype)exceptionWithOpenMode:(SCFileStreamOpenMode)mode;

SCL-20034: пустой путь к файлу потока

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

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

+ (instancetype)exceptionWithEmptyPath;

SCL-20035: обнаружен конец потока

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

+ (instancetype)exceptionWithEndOfFile:(NSString *)file;
+ (instancetype)exceptionWithEndOfFile;

SCL-20036: некорректное смещение в потоке

Ошибка возникает при попытке позиционировать указатель за пределы потока.

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

@property (assign, readonly, getter=seekError) SCSystemError seekError;
@property (assign, readonly, getter=offset) SCLong offset;
@property (assign, readonly, getter=whence) SCFileStreamOffsetWhence whence;
- (SCSystemError)seekError;
- (NSInteger)offset;

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

+ (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: некорректное направление смещения в потоке

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

@property (assign, readonly, getter=seekError) SCSystemError seekError;
@property (assign, readonly, getter=whence) SCFileStreamOffsetWhence whence;
- (SCSystemError)seekError;

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

+ (instancetype)exceptionWithWhence:(SCFileStreamOffsetWhence)whence path:(NSString *)path;
+ (instancetype)exceptionWithWhence:(SCFileStreamOffsetWhence)whence;

Класс SCCollectionException

Класс исключительной ситуации SCCollectionException обеспечивает обработку ошибок, которые могут возникнуть при работе с коллекциями библиотеки.


Свойства исключительной ситуации

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

@property (nonatomic, retain, readonly, getter=collectionName) NSString *collectionName;
@property (nonatomic, retain, readonly, getter=typeName) NSString *typeName;
@property (nonatomic, retain, readonly, getter=unsupported) NSString *unsupported;
@property (nonatomic, retain, readonly, getter=unknown) NSString *unknown;
@property (nonatomic, retain, readonly, getter=unexpected) NSString *unexpected;
@property (nonatomic, retain, readonly, getter=expected) NSString *expected;
@property (nonatomic, assign, readonly, getter=index) SCIndex index;
@property (nonatomic, assign, readonly, getter=range) NSRange range;
@property (nonatomic, retain, readonly, getter=indexSet) NSIndexSet *indexSet;
@property (nonatomic, assign, readonly, getter=indexesCount) SCULong indexesCount;
@property (nonatomic, assign, readonly, getter=objectsCount) SCULong objectsCount;
@property (nonatomic, retain, readonly, getter=key) NSString *key;
@property (nonatomic, assign, readonly, getter=keysCount) SCULong keysCount;
- (NSString *)collectionName;
- (NSString *)typeName;
- (NSString *)unsupported;
- (NSString *)unknown;
- (NSString *)unexpected;
- (NSString *)expected;
- (SCIndex)index;
- (NSRange)range;
- (NSIndexSet *)indexSet;
- (SCULong)indexesCount;
- (SCULong)objectsCount;
- (NSString *)key;
- (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 - исходная коллекция не существует

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

Для создания данной исключительной ситуации класс SCCollectionException декларирует следующие методы:

+ (instancetype)exceptionWithSource;

SCL-20042 - неподдерживаемый тип коллекции

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

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

@property (nonatomic, retain, readonly, getter=typeName) NSString *typeName;
- (NSString *)typeName;

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

+ (instancetype)exceptionWithUnsupportedType:(NSString *)type;

SCL-20043 - нарушение режима «только для чтения»

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

Класс SCCollectionException декларирует следующие классовые методы для создания данной исключительной ситуации:

+ (instancetype)exceptionWithReadOnlyType:(NSString *)type name:(NSString *)name;
+ (instancetype)exceptionWithReadOnlyType:(NSString *)type;

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


SCL-20044 - добавление нулевого указателя

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

+ (instancetype)exceptionWithItemType:(NSString *)type name:(NSString *)name;
+ (instancetype)exceptionWithItemType:(NSString *)type;

SCL-20045 - исходный объект не существует

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

Создание исключительной ситуации SCL-20045 выполняется следующими методами класса SCCollectionException:

+ (instancetype)exceptionWithObject;

SCL-20046 - неподдерживаемый класс

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

@property (nonatomic, retain, readonly, getter=unsupported) NSString *unsupported;
- (NSString *)unsupported;

Класс SCCollectionException для создания данной исключительной ситуации декларирует следующие классовые методы:

+ (instancetype)exceptionWithUnsupported:(NSString *)cname type:(NSString *)type name:(NSString *)name;
+ (instancetype)exceptionWithUnsupported:(NSString *)cname type:(NSString *)type;

SCL-20047 - неизвестный класс

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

@property (nonatomic, retain, readonly, getter=unknown) NSString *unknown;
- (NSString *)unknown;

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

+ (instancetype)exceptionWithUnknown:(NSString *)cname type:(NSString *)type name:(NSString *)name;
+ (instancetype)exceptionWithUnknown:(NSString *)cname type:(NSString *)type;

SCL-20048 - объект коллекции не поддерживает сравнивание

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

+ (instancetype)exceptionWithNotComparableType:(NSString *)type name:(NSString *)name;
+ (instancetype)exceptionWithNotComparableType:(NSString *)type;

SCL-20049 - коллекция не поддерживает операции сортировки

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

+ (instancetype)exceptionWithNotSortableType:(NSString *)type name:(NSString *)name;
+ (instancetype)exceptionWithNotSortableType:(NSString *)type;

SCL-20050 - некорректный сортировщик данных

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

+ (instancetype)exceptionWithSorterType:(NSString *)type name:(NSString *)name;
+ (instancetype)exceptionWithSorterType:(NSString *)type;

SCL-20052 - некорректный индекс объекта

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

@property (nonatomic, assign, readonly, getter=index) SCIndex index;
- (SCIndex)index;

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

+ (instancetype)exceptionWithIndex:(SCIndex)index name:(NSString *)name;
+ (instancetype)exceptionWithIndex:(SCIndex)index;

SCL-20053 - некорректный диапазон объектов

При обнаружении факта передачи какому-либо методу коллекции некорректного диапазона объектов генерируется исключительная ситуация SCL-20053. Ошибочный диапазон объектов при этом записывается в свойство range:

@property (nonatomic, assign, readonly, getter=range) NSRange range;
- (NSRange)range;

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

+ (instancetype)exceptionWithRange:(NSRange)range name:(NSString *)name;
+ (instancetype)exceptionWithRange:(NSRange)range;

SCL-20054 - некорректный список индексов

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

@property (nonatomic, retain, readonly, getter=indexSet) NSIndexSet *indexSet;
- (NSIndexSet *)indexSet;

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

+ (instancetype)exceptionWithIndexSet:(NSIndexSet *)indexSet name:(NSString *)name;
+ (instancetype)exceptionWithIndexSet:(NSIndexSet *)indexSet;

SCL-20055 - несоответствие количества индексов и объектов

Ряд методов индексируемых коллекций оперирует с множествами индексов и списками объектов. При этом количество индексов должно совпадать с количеством объектов. Если коллекция обнаруживает несоответствие между ними, генерируется исключительная ситуация SCL-20055. Сведения об ошибке хранятся в следующих свойствах:

@property (nonatomic, assign, readonly, getter=indexesCount) SCULong indexesCount;
@property (nonatomic, assign, readonly, getter=objectsCount) SCULong objectsCount;
- (SCULong)indexesCount;
- (SCULong)objectsCount;

Создание данной исключительной ситуации обеспечивают следующие методы класса SCCollectionException:

+ (instancetype)exceptionWithIndexesCount:(SCULong)indexes objectsCount:(SCULong)objects;

SCL-20056 - ошибка ключа объекта

Если коллекция обнаруживает передачу ей некорректного ключа к объекту (обычно применяются в словарях), то возникает ошибка SCL-20056. Ошибочный ключ хранится в свойстве SCCollectionException.key "key" экземпляра данной исключительной ситуации:

- (NSString *)key;
@property (nonatomic, retain, readonly, getter=key) NSString *key;

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

+ (instancetype)exceptionWithKey:(NSString *)key name:(NSString *)name;
+ (instancetype)exceptionWithKey:(NSString *)key;

SCL-20057 - несоответствие ключей и объектов

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

@property (nonatomic, assign, readonly, getter=keysCount) SCULong keysCount;
@property (nonatomic, assign, readonly, getter=objectsCount) SCULong objectsCount;
- (SCULong)keysCount;
- (SCULong)objectsCount;

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

+ (instancetype)exceptionWithKeysCount:(SCULong)keys objectsCount:(SCULong)objects;

SCL-20058 - пустое значение

Данная исключительная ситуация возникает при попытке назначить ключу пустое значение. Ошибочный ключ хранится в свойстве key:

@property (nonatomic, retain, readonly, getter=key) NSString *key;
- (NSString *)key;

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

+ (instancetype)exceptionValueForKey:(NSString *)key name:(NSString *)name;
+ (instancetype)exceptionValueForKey:(NSString *)key;

Класс SCTextException

Класс исключительной ситуации SCTextException обеспечивает обработку ошибок, которые могут возникнуть при работе механизма текстов библиотеки, а именно классов:


Свойства исключительной ситуации

Класс SCTextException объявляет ряд доступных только для чтения свойств и методов доступа к этим свойствам:

@property (nonatomic, retain, readonly, getter=textName) NSString *textName;
@property (nonatomic, retain, readonly, getter=string) NSString *string;
@property (nonatomic, assign, readonly, getter=index) SCIndex index;
@property (nonatomic, retain, readonly, getter=indexSet) NSIndexSet *indexSet;
@property (nonatomic, retain, readonly, getter=unsupported) NSString *unsupported;
@property (nonatomic, assign, readonly, getter=indexesCount) SCULong indexesCount;
@property (nonatomic, assign, readonly, getter=stringsCount) SCULong stringsCount;
@property (nonatomic, assign, readonly, getter=range) NSRange range;
@property (nonatomic, assign, readonly, getter=intersected) NSRange intersected;
@property (nonatomic, assign, readonly, getter=stream) SCStream *stream;
- (NSString *)textName;
- (NSString *)string;
- (SCIndex)index;
- (NSIndexSet *)indexSet;
- (NSString *)unsupported;
- (SCULong)indexesCount;
- (SCULong)stringsCount;
- (NSRange)range;
- (NSRange)intersected;
- (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 - исходный объект не существует

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

+ (instancetype)sourceExceptionWithName:(NSString *)name;
+ (instancetype)sourceException;

SCL-20062 - некорректный входной поток

Если при попытке загрузки текстового файла из потока будет обнаружена проблема с входным потоком (нулевой указатель на поток, поток не поддерживает операций чтения), текстовый объект генерирует исключительную ситуацию SCL-20062. Указатель на некорректный входной поток доступен через свойство stream:

@property (nonatomic, assign, readonly, getter=stream) SCStream *stream;
- (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 - работа с закрытым потоком

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

@property (nonatomic, assign, readonly, getter=stream) SCStream *stream;
- (SCStream *)stream;

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

+ (instancetype)exceptionWithClosedStream:(SCStream *)stream name:(NSString *)name;
+ (instancetype)exceptionWithClosedStream:(SCStream *)stream;

SCL-20066 - обнаружен неподдерживаемый класс

Если текстовый объект при обработке данных обнаруживает неподдерживаемый им класс, генерируется исключительная ситуация SCL-20066. Имя неподдерживаемого класса сохраняется в свойстве unsupported:

@property (nonatomic, retain, readonly, getter=unsupported) NSString *unsupported;
- (NSString *)unsupported;

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

+ (instancetype)exceptionWithUnsupported:(NSString *)unsupported name:(NSString *)name;
+ (instancetype)exceptionWithUnsupported:(NSString *)unsupported;

SCL-20067 - ошибка чтения данных из потока

Если в ходе загрузки строк из потока возникает ошибка чтения данных, то текстовый объект генерирует исключительную ситуацию SCL-20067, сохраняя в свойстве stream указатель на вызвавший ошибку поток:

@property (nonatomic, assign, readonly, getter=stream) SCStream *stream;
- (SCStream *)stream;

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

+ (instancetype)readErrorExceptionWithStream:(SCStream *)stream name:(NSString *)name;
+ (instancetype)readErrorExceptionWithStream:(SCStream *)stream;

SCL-20068 - пустой путь к текстовому файлу

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

+ (instancetype)emptyPathExceptionWithName:(NSString *)name;
+ (instancetype)emptyPathException;

SCL-20069 - нарушение уникальности строк

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

@property (nonatomic, retain, readonly, getter=string) NSString *string;
@property (nonatomic, assign, readonly, getter=index) SCIndex index;
- (NSString *)string;
- (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, assign, readonly, getter=stream) SCStream *stream;
- (SCStream *)stream;

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

+ (instancetype)exceptionWithOutputStream:(SCStream *)stream name:(NSString *)name;
+ (instancetype)exceptionWithOutputStream:(SCStream *)stream;

SCL-20072 - недопустимый индекс

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

@property (nonatomic, assign, readonly, getter=index) SCIndex index;
- (SCIndex)index;

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

+ (instancetype)exceptionWithIndex:(SCIndex)index name:(NSString *)name;
+ (instancetype)exceptionWithIndex:(SCIndex)index;

SCL-20073 - недопустимый диапазон строк

При обнаружении некорректного диапазона строк текстовый объект генерирует исключительную ситуацию SCL-20073, которая сохраняет обнаруженный диапазон в свойстве range:

@property (nonatomic, assign, readonly, getter=range) NSRange range;
- (NSRange)range;

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

+ (instancetype)exceptionWithRange:(NSRange)range name:(NSString *)name;
+ (instancetype)exceptionWithRange:(NSRange)range;

SCL-20074 - некорректный список индексов строк

Некорректный список индексов (список индексов, в котором есть хотя бы один некорректный индекс) вызывает ошибку SCL-20074, сохраняя этот список в свойстве indexSet:

@property (nonatomic, retain, readonly, getter=indexSet) NSIndexSet *indexSet;
- (NSIndexSet *)indexSet;

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

+ (instancetype)exceptionWithIndexSet:(NSIndexSet *)indexSet name:(NSString *)name;
+ (instancetype)exceptionWithIndexSet:(NSIndexSet *)indexSet;

SCL-20075 - несоответствие количества индексов и строк

Некоторые методы текстовых объектов принимают в качестве аргументов списки индексов и списки объектов. Если количество элементов в этих списках не совпадает, то генерируется исключительная ситуация SCL-20075. Класс SCTextException определяет следующие свойства и методы для получения информации о данной ошибке:

@property (nonatomic, assign, readonly, getter=indexesCount) SCULong indexesCount;
@property (nonatomic, assign, readonly, getter=stringsCount) SCULong stringsCount;
- (SCULong)indexesCount;
- (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, assign, readonly, getter=range) NSRange range;
@property (nonatomic, assign, readonly, getter=intersected) NSRange intersected;
- (NSRange)range;
- (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, assign, readonly, getter=stream) SCStream *stream;
- (SCStream *)stream;

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

+ (instancetype)writeErrorExceptionWithStream:(SCStream *)stream name:(NSString *)name;
+ (instancetype)writeErrorExceptionWithStream:(SCStream *)stream;

Группирующие классы

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


Класс SCDelegate

Класс SCDelegate объединяет в общую иерархию все классы-обработчики событий (классы делегирования). В текущей версии библиотеки данная иерархия имеет следующий вид:

delegates.png

Класс SCService

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

services.png

Доступ к информации о библиотеке

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

+ (NSString *)version;
+ (NSString *)fullVersion;
+ (SCUInteger)sclBuild;
+ (NSString *)libraryInformation;
+ (NSString *)compilationDate;
+ (NSString *)compilationDateTime;
+ (NSString *)compilationString;

Типы и константы

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


Стандартные типы данных

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

SCByte - Знаковый 8-битный целочисленный тип данных
SCShort - Знаковый 16-битный целочисленный тип данных
SCInteger - Знаковый 32-битный целочисленный тип данных
SCLong - Знаковый 64-битный целочисленный тип данных
SCUByte - Беззнаковый 8-битный целочисленный тип данных
SCUShort - Беззнаковый 16-битный целочисленный тип данных
SCUInteger - Беззнаковый 32-битный целочисленный тип данных
SCULong - Беззнаковый 64-битный целочисленный тип данных
SCFloat - Тип данных с плавающей точкой одинарной точности
SCDouble - Тип данных с плавающей точкой двойной точности

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

SCTypeUnspecified = 0 - Неопределенный тип данных
SCTypeByte = 1 - Знаковый 8-битный целочисленный тип данных
SCTypeShort = 2 - Знаковый 16-битный целочисленный тип данных
SCTypeInteger = 3 - Знаковый 32-битный целочисленный тип данных
SCTypeLong = 4 - Знаковый 64-битный целочисленный тип данных
SCTypeUByte = 5 - Беззнаковый 8-битный целочисленный тип данных
SCTypeUShort = 6 - Беззнаковый 16-битный целочисленный тип данных
SCTypeUInteger = 7 - Беззнаковый 32-битный целочисленный тип данных
SCTypeULong = 8 - Беззнаковый 64-битный целочисленный тип данных
SCTypeFloat = 9 - Тип данных с плавающей точкой одинарной точности
SCTypeDouble = 10 - Тип данных с плавающей точкой двойной точности
SCTypeChar = 11 - Односимвольный тип данных
SCTypeBool = 12 - Логический тип данных
SCTypeUChar = 13 - Односимвольный беззнаковый тип данных
SCTypeSignedLong = 14 - Знаковый длинный целочисленный тип данных
SCTypeUnsignedLong = 15 - Беззнаковый длинный целочисленный тип данных

Специализированные типы данных

Библиотека в файле SCTypes.h объявляет следующие специализированные типы данных:

SCSize - Беззнаковый тип размера данных

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

Для поддержки коллекций в файле SCTypes.h декларируются следующие типы данных:

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

Другие типы данных

Файл SCTypes.h содержит объявление следующих дополнительных типов данных:

SCCapacity - Тип разрядности целых чисел

Макросы

Файл SCConstants.h содержит объявление следующих макросов:

#define SCLS( string) NSLocalizedString( string, nil)
#define __abstract__( name) { @throw [SCAbstractMethodException exceptionWithMethod:name]; }