antonio's blog

antonio's blog


Блог о всяком разном, связанном с разработкой ПО. Пишу редко, когда есть время и желание.

Anton Dobkin
Author

Share


Tags


Класс NSSet

Anton DobkinAnton Dobkin

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

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

Объекты класса NSSet заполняются множеством объектов при создании и являются неизменяемыми (immutable).

Принимаемые классом протоколы:

Создание набора

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

NSSet *mySet = nil;  
mySet = [NSSet setWithObjects:@"someString", @"someString2", nil];  
NSLog(@"%@", mySet);  

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

Другие методы создания набора:

+set - создает пустой набор

NSSet *mySet = [NSSet set];  
NSLog(@"%@", mySet);  

+setWithArray: - создает набор из массива NSArray. Метод принимает один аргумент - массив добавляемых объектов. Если в массиве объект встречается более одного раза, то в набор он будет добавлен только один раз. Каждый объект из массива, добавляемый в набор, захватывается с помощью посылки сообщения retain.

NSArray *myArray = [NSArray arrayWithObjects: @"one", @"two", @"three", nil];  
NSSet *mySet = [NSSet setWithArray:myArray];  
NSLog(@"%@", mySet);  

+setWithObject: - создает набор с единственным элементом. Метод принимает один аргумент - добавляемый объект. Добавляемый объект захватывается с помощью посылки сообщения retain.

NSSet *mySet = [NSSet setWithObject:@"one"];  
NSLog(@"%@", mySet);  

+setWithObjects:count: - создает набор из C массива. Метод принимает два аргумента, первый - C массив добавляемых в набор объектов, второй - кол-во элементов в C массиве. Если в массиве объект встречается более одного раза, то в набор он будет добавлен только один раз. Каждый объект из массива, добавляемый в набор, захватывается с помощью посылки сообщения retain.

id cArray[3] = {@"one", @"two", @"three"};  
NSSet *mySet = [NSSet setWithObjects:cArray count:3];  
NSLog(@"%@", mySet);  

+setWithSet: - создает набор из уже существующего набора. Метод принимает один аргумент - существующий набор. Каждый объект из существующего набора, перед добавлением в новый набор, захватывается с помощью посылки сообщения retain.

NSSet *mySet1 = [NSSet setWithObjects: @"one", @"two", @"three", nil];  
NSLog(@"%@", mySet1);  
NSSet *mySet2 =  [NSSet setWithSet: mySet1];  
[mySet1 release];
NSLog(@"%@", mySet2);  
[mySet2 release];

– setByAddingObject: - создает новый набор из текущего с добавлением нового объекта переданного в качестве аргумента. Каждый объект из
набора переданного в аргументе захватывается с помощью посылки сообщения retain.

NSSet *mySet1 = [NSSet setWithObjects: @"one", @"two", @"three", nil];  
NSLog(@"%@", mySet1);  
NSSet *mySet2 = [mySet1 setByAddingObject: @"four"];  
NSLog(@"%@", mySet2);  

– setByAddingObjectsFromSet: - создает новый набор из текущего с добавлением объектов из набора переданного в аргументе. Каждый объект из переданного набора захватывается с помощью посылки сообщения retain

NSSet *mySet1 = [NSSet setWithObjects: @"one", @"two", @"three", nil];  
NSLog(@"%@", mySet1);  
NSSet *mySet2 = [NSSet setWithObjects: @"four", @"five", nil];  
NSLog(@"%@", mySet2);  
NSSet *mySet3 = [mySet1 setByAddingObjectsFromSet: mySet2];  
NSLog(@"%@", mySet3);  

– setByAddingObjectsFromArray: - создает новый набор из текущего с добавлением объектов из массива переданного в аргументе. Если в массиве объект встречается более одного раза, то в набор он будет добавлен только один раз. Каждый объект из массива, добавляемый в набор, захватывается с помощью посылки сообщения retain.

NSSet *mySet1 = [NSSet setWithObjects: @"one", @"two", @"three", nil];  
NSLog(@"%@", mySet1);  
NSArray *myArray = [NSArray arrayWithObjects: @"four", @"five", @"six", nil];  
NSSet *mySet2 = [mySet1 setByAddingObjectsFromArray: myArray];  
NSLog(@"%@", mySet2);  

Все методы возвращают объект класса NSSet.

Инициализация набора

Методы инициализации экземпляра NSSet:

–initWithArray: - инициализирует созданный набор объектами из массива. Метод принимает один аргумент - массив добавляемых в набор объектов. Если в массиве объект встречается более одного раза, то в набор он будет добавлен только один раз. Каждый объект из массива, добавляемый в набор, захватывается с помощью посылки сообщения retain.

NSArray *myArray = [NSArray arrayWithObjects: @"one", @"two", @"three", nil];  
NSSet *mySet = [[NSSet alloc] initWithArray: myArray];  
NSLog(@"%@", mySet);

[mySet release];

–initWithObjects: - инициализирует созданный набор объектами. Метод, через запятую, принимает nil-терминированный список объектов добавляемых в набор. Если объект встречается более одного раза в передаваемом списке, то он будет добавлен только один раз. Каждый объект, добавляемый в набор, захватывается с помощью посылки сообщения retain.

NSSet *mySet = [[NSSet alloc] initWithObjects: @"one", @"two", @"three", nil];  
NSLog(@"%@", mySet);  
[mySet release];

–initWithObjects:count: - инициализирует созданный набор объектами из C массива. Метод принимает два аргумента, первый - C массив добавляемых в набор объектов, второй - Кол-во элементов в C массиве. Если в массиве объект встречается более одного раза, то в набор он будет добавлен только один раз. Каждый объект из массива, добавляемый в набор, захватывается с помощью посылки сообщения retain.

id cArray[3] = {@"one", @"two", @"three"};  
NSSet *mySet = [[NSSet alloc] initWithObjects:cArray count:3];  
NSLog(@"%@", mySet);  
[mySet release];

–initWithSet: - инициализирует созданный набор объектами из существующего набора. Метод принимает один аргумент - существующий набор. Каждый объект из существующего набора, добавляемый в новый набор, захватывается с помощью посылки сообщения retain.

NSSet *mySet1 = [[NSSet alloc] initWithObjects: @"one", @"two", @"three", nil];  
NSLog(@"%@", mySet1);  
NSSet *mySet2 =  [[NSSet alloc] initWithSet: mySet1];  
[mySet1 release];
NSLog(@"%@", mySet2);  
[mySet2 release];

–initWithSet:copyItems: - метод похож на initWithSet:, но в отличие от него может создавать копию добавляемых в новый набор объектов. Метод принимает два аргумента, первый - существующий набор объектов, второй - флаг копирования. Если значение второго аргумента YES, то перед добавлением объектов в новый наборе будет создана их копия, каждому объекту посылается сообщение copyWithZone: Добавляемые в набор объекты должны принимать протокол NSCopying. Если значение второго аргумента NO, то каждый объект из существующего набора, добавляемый в новый набор, захватывается с помощью посылки сообщения retain.

Кол-во элементов в наборе

Для того чтобы узнать сколько элементов содержится в наборе необходимо вызвать метод объекта count

NSSet *mySet1 = [NSSet setWithObjects: @"one", @"two", @"three", nil];  
NSArray *myArray = [NSArray arrayWithObjects: @"four", @"five", @"six", nil];  
NSSet *mySet2 = [mySet1 setByAddingObjectsFromArray: myArray];  
NSInteger countElements = [mySet2 count];

NSLog(@"%ld", countElements);  

Сравнение наборов

Методы для сравнения наборов:

–isSubsetOfSet: - проверяет является ли текущий набор подмножеством набора переданного в аргументе. Метод возвращает YES, если каждый элемент из текущего набора присутствует в наборе переданном в аргументе, иначе метод возвращает NO

NSSet *mySet1 = [NSSet setWithObjects: @"one", @"two", @"three", nil];  
NSSet *mySet2 = [NSSet setWithObjects: @"one", @"two", @"three", @"four", nil];  
if([mySet1 isSubsetOfSet:mySet2]) {  
  NSLog(@"mySet1 is subset of mySet2");
}

–intersectsSet: - проверяет присутствует ли хотя бы один элемент из текущего набора в наборе переданном в аргументе. Метод возвращает YES, если хотя бы один элемент из текущего набора присутствует в наборе переданном в аргументе.

NSSet *mySet1 = [NSSet setWithObjects: @"one", @"two", @"three", nil];  
NSSet *mySet2 = [NSSet setWithObjects: @"three", @"five", @"six", @"four", nil];  
if([mySet1 intersectsSet:mySet2]) {  
  //...
}

–isEqualToSet: - Проверяет равенство текущего набора и набора переданного в аргументе. Метод возвращает YES, если оба набора идентичны.

NSSet *mySet1 = [NSSet setWithObjects: @"one", @"two", @"three", nil];  
NSSet *mySet2 = [NSSet setWithObjects: @"one", @"two", @"three", nil];  
if([mySet1 isEqualToSet:mySet2]) {  
  NSLog(@"mySet1 is equal to mySet2");
}

Доступ к элементам набора

Методы доступа к элементам набора:

–allObjects - возвращает массив NSArray со всеми объектами из набора. Если в наборе нет элементов, то метод вернет пустой массив

–anyObject - Возвращает один из объектов набора. Нет гарантий, что объект будет случайным при каждом вызове

-containsObject: - проверяет содержится ли в текущем наборе переданный в аргументе элемент. Метод возвращает YES, если элемент присутствует в наборе, иначе NO

NSSet *mySet1 = [NSSet setWithObjects: @"one", @"two", @"three", nil];  
if([mySet1 containsObject: @"two"]) {  
  // ...
}

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

-filteredSetUsingPredicate: - возвращает новый набор с объектами соответствующими указанному фильтру - предикату.

NSSet *mySet1 = [NSSet setWithObjects: @"one", @"two", @"three", nil];  
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF beginswith 't'"];  
NSSet *mySet2 = [mySet1 filteredSetUsingPredicate: predicate];  
NSLog(@"%@", mySet2);  // mySet2 содержит @"two" @"three"  

-makeObjectsPerformSelector: - посылает каждому объекту из набора сообщение указанное в аргументе, другими словами выполняет метод, название которого передано в качестве значения аргумента. Если в качестве значения аргумента будет передано значение NULL, то будет выброшено исключение NSInvalidArgumentException

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

-objectsPassingTest: - возвращает новый набор с объектами, которые прошли тест в переданном блоке. В блок передается два аргумента, первый - объект из набора, второй - флаг остановки, если установить его в NO, то перебор элементов будет остановлен. Блок должен вернуть YES, если объект прошел тест, иначе NO. Прототип блока:

BOOL (^)(id obj, BOOL *stop)`  
`NSSet *mySet1 = [NSSet setWithObjects: @"one", @"two", [NSNumber numberWithInt:10], nil];

NSSet *mySet2 = [mySet1 objectsPassingTest:^BOOL(id obj, BOOL *stop) {  
  if([obj isKindOfClass:[NSString class]]) {
    return YES;
  }
  return NO;
}];

NSLog(@"%@", mySet2);   // mySet2 содержит @"one" @"two"  

-objectsWithOptions:passingTest: - аналогичен методу objectsPassingTest: но в отличие от первого в качестве значение первого аргумента принимает битовую маску (NSEnumerationOptions) - параметры перебора объектов набора. Вторым аргументом метод принимает блок используемый для тестирования. В блок передается два аргумента, первый - объект из набора, второй - флаг остановки, если установить его в NO, то перебор элементов будет остановлен. Блок должен вернуть YES, если объект прошел тест, иначе NO. Прототип блока:

BOOL (^)(id obj, BOOL *stop)  

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

NSSet *mySet1 = [NSSet setWithObjects: @"one", @"two", @"three", nil];  
NSEnumerator *enumerator = [mySet objectEnumerator];  
id obj = nil;  
while ((obj = [enumerator nextObject])) {  
   //....
}

-enumerateObjectsUsingBlock: - проходит по всем элементам набора и выполняет указанный блок для каждого элемента. В блок передается два аргумента, первый - объект из набора, второй - флаг остановки, если установить его в NO, то перебор элементов будет остановлен. Прототип блока:

void (^)(id obj, BOOL *stop)  

-enumerateObjectsWithOptions:usingBlock: - аналогичен методу enumerateObjectsUsingBlock: но в отличие от первого в качестве значения первого аргумента принимает битовую маску (NSEnumerationOptions) - параметры перебора объектов набора. Вторым аргументом метод принимает блок применяемый для каждого объекта набора. В блок передается два аргумента, первый - объект из набора, второй - флаг остановки, если установить его в NO, то перебор элементов будет остановлен. Прототип блока:

void (^)(id obj, BOOL *stop)  

–sortedArrayUsingDescriptors: - Возвращает массив объектов из набора, отсортированный при помощи указанного массива дескрипторов сортировки

Anton Dobkin
Author

Anton Dobkin

Comments