Значения и наборы
Несмотря на то, что Objective C является языком объектно-ориентированного программирования, это - надмножество C, что означает, что можно использовать любой стандарт C скалярные (необъектные) типы как int
, float
и char
в коде Objective C. Существуют также дополнительные скалярные типы, доступные в Сенсорных приложениях Какао и Какао, такой как NSInteger
, NSUInteger
и CGFloat
, которые имеют различные определения в зависимости от целевой архитектуры.
Скалярные типы используются в ситуациях, где Вам просто не нужны преимущества (или связанные издержки) использования объекта представлять значение. В то время как строки символов обычно представляются как экземпляры NSString
класс, числовые значения часто сохранены в скалярных локальных переменных или свойствах.
Возможно объявить массив C-стиля в Objective C, но Вы найдете, что наборы в Сенсорных приложениях Какао и Какао обычно представляются с помощью экземпляров классов как NSArray
или NSDictionary
. Эти классы могут только использоваться для сбора объектов Objective C, что означает, что необходимо будет создать экземпляры классов как NSValue
, NSNumber
или NSString
для представления значений, прежде чем можно будет добавить их к набору.
Предыдущие главы в этом руководстве делают частое использование NSString
класс и его инициализация и методы фабрики классов, а также Objective C @"string"
литерал, предлагающий краткий синтаксис для создания NSString
экземпляр. Эта глава объясняет, как создать NSValue
и NSNumber
объекты, с помощью или вызовов метода или через Objective C оценивают литеральный синтаксис.
Основные типы примитивов C доступны в Objective C
Каждый стандарт C скалярные типы переменных доступен в Objective C:
int someInteger = 42; |
float someFloatingPointNumber = 3.1415; |
double someDoublePrecisionFloatingPointNumber = 6.02214199e23; |
а также стандарт C операторы:
int someInteger = 42; |
someInteger++; // someInteger == 43 |
int anotherInteger = 64; |
anotherInteger--; // anotherInteger == 63 |
anotherInteger *= 2; // anotherInteger == 126 |
Если Вы используете скалярный тип для свойства Objective-C, как это:
@interface XYZCalculator : NSObject |
@property double currentValue; |
@end |
также возможно использовать операторов C на свойстве при доступе к значению через точечный синтаксис, как это:
@implementation XYZCalculator |
- (void)increment { |
self.currentValue++; |
} |
- (void)decrement { |
self.currentValue--; |
} |
- (void)multiplyBy:(double)factor { |
self.currentValue *= factor; |
} |
@end |
Точечный синтаксис является просто синтаксической оберткой вокруг вызовов метода доступа, таким образом, каждая из операций в этом примере эквивалентна первому использованию получить метод доступа получить значение, затем выполняя работу, затем с помощью метода доступа набора установить значение в результат.
Objective C определяет дополнительные типы примитивов
BOOL
скалярный тип определяется в Objective C для содержания булева значения, которое является также YES
или NO
. Поскольку Вы могли бы ожидать, YES
логически эквивалентно true
и 1
, в то время как NO
эквивалентно false
и 0
.
Много параметров к методам на Сенсорных объектах Какао и Какао также используют специальные скалярные числовые типы, такой как NSInteger
или CGFloat
.
Например, NSTableViewDataSource
и UITableViewDataSource
протоколы (описанный в предыдущей главе) у обоих есть методы, запрашивающие число строк вывести на экран:
@protocol NSTableViewDataSource <NSObject> |
- (NSInteger)numberOfRowsInTableView:(NSTableView *)tableView; |
... |
@end |
Эти типы, как NSInteger
и NSUInteger
, определяются по-другому в зависимости от целевой архитектуры. При создании для 32-разрядной среды (такой что касается iOS), они - 32-разрядные целые числа со знаком и целые без знака соответственно; при создании для 64-разрядной среды (такой что касается современного времени выполнения OS X) они - 64-разрядные целые числа со знаком и целые без знака соответственно.
Если Вы могли бы передавать значения через границы API (и внутренний и экспортируемый APIs), такие как параметры или возвращаемые значения в методе или вызовах функции между Вашим кодом приложения и платформой, это - наиболее успешная практика для использования этих специфичных для платформы типов.
Для локальных переменных, таких как счетчик в цикле, хорошо использовать основные типы C, если Вы знаете, что значение в стандартных пределах.
C структуры может содержать примитивные значения
Некоторое Касание Какао и Какао API использует структуры C для содержания их значений. Как пример, возможно попросить у строкового объекта диапазона подстроки, как это:
NSString *mainString = @"This is a long string"; |
NSRange substringRange = [mainString rangeOfString:@"long"]; |
NSRange
структура содержит расположение и длину. В этом случае, substringRange
будет содержать диапазон {10,4}
— “l
” в начале @"long"
символ в основанном на нуле индексе 10
в mainString
, и @"long"
4
символы в длине.
Точно так же, если необходимо записать пользовательский код для прорисовки, необходимо будет взаимодействовать с Кварцем, требующим структур, базируемых вокруг CGFloat
тип данных, как NSPoint
и NSSize
на OS X и CGPoint
и CGSize
на iOS. Снова, CGFloat
определяется по-другому в зависимости от целевой архитектуры.
Для получения дополнительной информации о Кварце 2D механизм получения посмотрите Кварц 2D Руководство по программированию.
Объекты могут представлять примитивные значения
Если необходимо представлять скалярное значение как объект, такой, работая с классами набора, описанными в следующем разделе, можно использовать один из основных классов значения, предоставленных Касанием Какао и Какао.
Строки представлены экземплярами класса NSString
Поскольку Вы видели в предыдущих главах, NSString
используется для представления строки символов, как Hello World
. Существуют различные способы создать NSString
объекты, включая стандартное выделение и инициализацию, методы фабрики классов или литеральный синтаксис:
NSString *firstString = [[NSString alloc] initWithCString:"Hello World!" |
encoding:NSUTF8StringEncoding]; |
NSString *secondString = [NSString stringWithCString:"Hello World!" |
encoding:NSUTF8StringEncoding]; |
NSString *thirdString = @"Hello World!"; |
Каждый из этих примеров эффективно выполняет ту же вещь — создание строкового объекта, представляющего предоставленные символы.
Основное NSString
класс является неизменным, что означает, что его содержание установлено при создании и не может позже быть изменено. Если необходимо представлять различную строку, необходимо создать новый строковый объект, как это:
NSString *name = @"John"; |
name = [name stringByAppendingString:@"ny"]; // returns a new string object |
NSMutableString
класс является непостоянным подклассом NSString
, и позволяет Вам изменять его символьное содержание во время выполнения с помощью методов как appendString:
или appendFormat:
, как это:
NSMutableString *name = [NSMutableString stringWithString:@"John"]; |
[name appendString:@"ny"]; // same object, but now represents "Johnny" |
Строки формата используются для создания строк из других объектов или значений
Если необходимо создать строку, содержащую значения переменных, необходимо работать со строкой формата. Это позволяет Вам использовать спецификаторы формата, чтобы указать, как вставляются значения:
int magicNumber = ... |
NSString *magicString = [NSString stringWithFormat:@"The magic number is %i", magicNumber]; |
Спецификаторы доступного формата описаны в Спецификаторах Формата строки. Для получения дополнительной информации о строках в целом, см. Строковое Руководство по программированию.
Числа представлены экземплярами класса NSNumber
NSNumber
класс используется для представления любого из основных скалярных типов C, включая char
, double
, float
, int
, long
, short
, и unsigned
варианты каждого, а также тип булевской переменной Objective C, BOOL
.
Как с NSString
, у Вас есть множество опций создать NSNumber
экземпляры, включая выделение и инициализацию или методы фабрики классов:
NSNumber *magicNumber = [[NSNumber alloc] initWithInt:42]; |
NSNumber *unsignedNumber = [[NSNumber alloc] initWithUnsignedInt:42u]; |
NSNumber *longNumber = [[NSNumber alloc] initWithLong:42l]; |
NSNumber *boolNumber = [[NSNumber alloc] initWithBOOL:YES]; |
NSNumber *simpleFloat = [NSNumber numberWithFloat:3.14f]; |
NSNumber *betterDouble = [NSNumber numberWithDouble:3.1415926535]; |
NSNumber *someChar = [NSNumber numberWithChar:'T']; |
Также возможно создать NSNumber
экземпляры с помощью синтаксиса литерала Objective C:
NSNumber *magicNumber = @42; |
NSNumber *unsignedNumber = @42u; |
NSNumber *longNumber = @42l; |
NSNumber *boolNumber = @YES; |
NSNumber *simpleFloat = @3.14f; |
NSNumber *betterDouble = @3.1415926535; |
NSNumber *someChar = @'T'; |
Эти примеры эквивалентны использованию NSNumber
методы фабрики классов.
Как только Вы создали NSNumber
экземпляр возможно запросить скалярное значение с помощью одного из методов доступа:
int scalarMagic = [magicNumber intValue]; |
unsigned int scalarUnsigned = [unsignedNumber unsignedIntValue]; |
long scalarLong = [longNumber longValue]; |
BOOL scalarBool = [boolNumber boolValue]; |
float scalarSimpleFloat = [simpleFloat floatValue]; |
double scalarBetterDouble = [betterDouble doubleValue]; |
char scalarChar = [someChar charValue]; |
NSNumber
класс также предлагает методы для работы с дополнительными типами примитивов Objective C. Если необходимо создать объектное представление скаляра NSInteger
и NSUInteger
типы, например, удостоверяются, что Вы используете корректные методы:
NSInteger anInteger = 64; |
NSUInteger anUnsignedInteger = 100; |
NSNumber *firstInteger = [[NSNumber alloc] initWithInteger:anInteger]; |
NSNumber *secondInteger = [NSNumber numberWithUnsignedInteger:anUnsignedInteger]; |
NSInteger integerCheck = [firstInteger integerValue]; |
NSUInteger unsignedCheck = [secondInteger unsignedIntegerValue]; |
Все NSNumber
экземпляры являются неизменными, и нет никакого непостоянного подкласса; при необходимости в различном числе просто используйте другого NSNumber
экземпляр.
Представляйте другие значения Используя экземпляры класса NSValue
NSNumber
класс является самостоятельно подклассом основного NSValue
класс, обеспечивающий объектную обертку вокруг единственного значения или элемента данных. В дополнение к основным скалярным типам C, NSValue
может также использоваться для представления указателей и структур.
NSValue
класс предлагает различные методы фабрики создать ценность с данной стандартной структурой, упрощающей создавать экземпляр для представления, например, NSRange
, как пример от ранее в главе:
NSString *mainString = @"This is a long string"; |
NSRange substringRange = [mainString rangeOfString:@"long"]; |
NSValue *rangeValue = [NSValue valueWithRange:substringRange]; |
Также возможно создать NSValue
объекты представлять пользовательские структуры. Если у Вас есть определенная потребность использовать структуру C (а не объект Objective C), чтобы хранить информацию, как это:
typedef struct { |
int i; |
float f; |
} MyIntegerFloatStruct; |
можно создать NSValue
экземпляр путем обеспечения указателя на структуру, а также закодированный тип Objective C. @encode()
директива компилятора используется для создания корректного типа Objective C, как это:
struct MyIntegerFloatStruct aStruct; |
aStruct.i = 42; |
aStruct.f = 3.14; |
NSValue *structValue = [NSValue value:&aStruct |
withObjCType:@encode(MyIntegerFloatStruct)]; |
Стандарт C ссылочный оператор (&
) используется для обеспечения адреса aStruct
для value
параметр.
Большинство наборов является объектами
Несмотря на то, что возможно использовать массив C для содержания набора скалярных значений или даже объектных указателей, большинство наборов в коде Objective C является экземплярами одного из Сенсорных классов набора Какао и Какао, как NSArray
, NSSet
и NSDictionary
.
Эти классы используются для управления группами объектов, что означает любой элемент, который Вы хотите добавить к набору, должен быть экземпляр класса Objective C. Если необходимо добавить скалярное значение, необходимо сначала создать подходящее NSNumber
или NSValue
экземпляр для представления его.
Вместо того, чтобы так или иначе поддерживать отдельную копию каждого собранного объекта, классы набора используют сильные ссылки для отслеживания их содержание. Это означает, что любой объект, который Вы добавляете к набору, будет поддержан, по крайней мере, пока набор поддерживается, как описано в Управляют Графом объектов через Владение и Ответственность.
В дополнение к отслеживанию их содержания каждый из Сенсорных классов набора Какао и Какао упрощает выполнять определенные задачи, такие как перечисление, получая доступ к конкретным изделиям, или узнавая, является ли определенный объект частью набора.
Основное NSArray
, NSSet
и NSDictionary
классы являются неизменными, что означает, что их содержание установлено при создании. У каждого также есть непостоянный подкласс, чтобы позволить Вам добавлять или удалять объекты по желанию.
Для получения дополнительной информации о различных классах набора, доступных в Касании Какао и Какао, посмотрите, что Наборы Программируют Темы.
Массивам упорядочивают наборы
NSArray
используется для представления упорядоченного набора объектов. Единственное требование - то, что каждый элемент является объектом Objective C — нет никакого требования для каждого объекта быть экземпляром того же класса.
Для поддержания порядка в массиве каждый элемент сохранен в основанном на нуле индексе, как показано на рисунке 6-1.
Создание массивов
Как с классами значения, описанными ранее в этой главе, можно создать массив посредством выделения и инициализации, методов фабрики классов или литерального синтаксиса.
Существует множество различной инициализации и методов фабрики, доступных, в зависимости от числа объектов:
+ (id)arrayWithObject:(id)anObject; |
+ (id)arrayWithObjects:(id)firstObject, ...; |
- (id)initWithObjects:(id)firstObject, ...; |
arrayWithObjects:
и initWithObjects:
методы оба берут завершенное нолем, переменное число параметров, что означает, что необходимо включать nil
как последнее значение, как это:
NSArray *someArray = |
[NSArray arrayWithObjects:someObject, someString, someNumber, someValue, nil]; |
Этот пример создает массив как один показанный ранее на рисунке 6-1. Первый объект, someObject
, будет иметь индекс массива 0
; последний объект, someValue
, будет иметь индекс 3
.
Если одно из предоставленных значений, возможно усечь список элементов непреднамеренно nil
, как это:
id firstObject = @"someString"; |
id secondObject = nil; |
id thirdObject = @"anotherString"; |
NSArray *someArray = |
[NSArray arrayWithObjects:firstObject, secondObject, thirdObject, nil]; |
В этом случае, someArray
будет содержать только firstObject
, потому что nil
secondObject
был бы интерпретирован как конец списка элементов.
Литеральный синтаксис
Также возможно создать массив с помощью литерала Objective C, как это:
NSArray *someArray = @[firstObject, secondObject, thirdObject]; |
Вы не должны завершать список объектов с nil
при использовании этого литерального синтаксиса, и фактически nil
недопустимое значение. При попытке выполнить следующий код, например, Вы получите исключение во время выполнения:
id firstObject = @"someString"; |
id secondObject = nil; |
NSArray *someArray = @[firstObject, secondObject]; |
// exception: "attempt to insert nil object" |
Если действительно необходимо представлять a nil
значение в одном из классов набора, необходимо использовать NSNull
singleton-класс, как описано в Представляют ноль с NSNull.
Запросы объектов массива
Как только Вы создали массив, можно запросить его для получения информации как число объектов, или содержит ли он данный элемент:
NSUInteger numberOfItems = [someArray count]; |
if ([someArray containsObject:someString]) { |
... |
} |
Можно также запросить массив для элемента в данном индексе. Вы доберетесь за пределы исключение во время выполнения, при попытке запросить недопустимый индекс, таким образом, необходимо всегда проверять число элементов сначала:
if ([someArray count] > 0) { |
NSLog(@"First item is: %@", [someArray objectAtIndex:0]); |
} |
Этот пример проверяет, больше ли число элементов, чем нуль. Если так, это регистрирует описание первого элемента, имеющего индекс нуля.
Преобразование в нижний индекс
Существует также нижняя альтернатива синтаксиса использованию objectAtIndex:
, который точно так же, как получает доступ к значению в стандарте C массив. Предыдущий пример мог быть переписан как это:
if ([someArray count] > 0) { |
NSLog(@"First item is: %@", someArray[0]); |
} |
Сортировка объектов массива
NSArray
класс также предлагает множество методов для сортировки его собранных объектов. Поскольку NSArray
является неизменным, каждый из этих методов возвращает новый массив, содержащий элементы в сортированном порядке.
Как пример, можно сортировать массив строк результатом вызова compare:
на каждой строке, как это:
NSArray *unsortedStrings = @[@"gammaString", @"alphaString", @"betaString"]; |
NSArray *sortedStrings = |
[unsortedStrings sortedArrayUsingSelector:@selector(compare:)]; |
Переменчивость
Несмотря на то, что NSArray
сам класс является неизменным, это не имеет никакого влияния ни на какие собранные объекты. Если Вы добавляете непостоянную строку к неизменному массиву, например, как это:
NSMutableString *mutableString = [NSMutableString stringWithString:@"Hello"]; |
NSArray *immutableArray = @[mutableString]; |
нет ничего, чтобы мешать Вам видоизменить строку:
if ([immutableArray count] > 0) { |
id string = immutableArray[0]; |
if ([string isKindOfClass:[NSMutableString class]]) { |
[string appendString:@" World!"]; |
} |
} |
Если необходимо быть в состоянии добавить или удалить объекты из массива после начального создания, необходимо будет использовать NSMutableArray
, который добавляет множество методов, чтобы добавить, удалить или заменить один или несколько объектов:
NSMutableArray *mutableArray = [NSMutableArray array]; |
[mutableArray addObject:@"gamma"]; |
[mutableArray addObject:@"alpha"]; |
[mutableArray addObject:@"beta"]; |
[mutableArray replaceObjectAtIndex:0 withObject:@"epsilon"]; |
Этот пример создает массив, заканчивающийся с объектами @"epsilon"
, @"alpha"
, @"beta"
.
Также возможно сортировать непостоянный массив на месте, не создавая вторичный массив:
[mutableArray sortUsingSelector:@selector(caseInsensitiveCompare:)]; |
В этом случае содержавшие элементы будут сортированы в возрастание, нечувствительный к регистру порядок @"alpha"
, @"beta"
, @"epsilon"
.
Наборам не упорядочивают наборы
NSSet
подобно массиву, но поддерживает неупорядоченную группу отдельных объектов, как показано на рисунке 6-2.
Поскольку наборы не поддерживают порядок, они предлагают повышение производительности по массивам когда дело доходит до тестирования на членство.
Основное NSSet
класс является снова неизменным, таким образом, его содержание должно быть указано при создании, с помощью или выделения и инициализации или метода фабрики классов, как это:
NSSet *simpleSet = |
[NSSet setWithObjects:@"Hello, World!", @42, aValue, anObject, nil]; |
Как с NSArray
, initWithObjects:
и setWithObjects:
методы оба берут завершенное нолем, переменное число параметров. Непостоянное NSSet
подкласс NSMutableSet
.
Даже при попытке добавить объект несколько раз, наборы только хранят одну ссылку на отдельный объект:
NSNumber *number = @42; |
NSSet *numberSet = |
[NSSet setWithObjects:number, number, number, number, nil]; |
// numberSet only contains one object |
Для получения дополнительной информации о наборах посмотрите Наборы: неупорядоченные Наборы Объектов.
Словари собирают пары ключ/значение
Вместо того, чтобы просто поддерживать упорядоченный или неупорядоченный набор объектов, NSDictionary
хранит объекты против данных ключей, которые могут тогда использоваться для извлечения.
Это - наиболее успешная практика для использования строковых объектов в качестве ключей словаря, как показано на рисунке 6-3.
Создание словарей
Можно создать словари с помощью или выделения и инициализации или методов фабрики классов, как это:
NSDictionary *dictionary = [NSDictionary dictionaryWithObjectsAndKeys: |
someObject, @"anObject", |
@"Hello, World!", @"helloString", |
@42, @"magicNumber", |
someValue, @"aValue", |
nil]; |
Обратите внимание на то, что для dictionaryWithObjectsAndKeys:
и initWithObjectsAndKeys:
методы, каждый объект указан перед его ключом, и снова, должен быть завершен нолем список объектов и ключей.
Литеральный синтаксис
Objective C также предлагает литеральный синтаксис для создания словаря, как это:
NSDictionary *dictionary = @{ |
@"anObject" : someObject, |
@"helloString" : @"Hello, World!", |
@"magicNumber" : @42, |
@"aValue" : someValue |
}; |
Обратите внимание на то, что для литералов словаря, ключ указан перед его объектом и не завершается нолем.
Запросы словарей
Как только Вы создали словарь, можно попросить у него объекта, хранившего против данного ключа, как это:
NSNumber *storedNumber = [dictionary objectForKey:@"magicNumber"]; |
Если объект не найден, objectForKey:
метод возвратится nil
.
Существует также нижняя альтернатива синтаксиса использованию objectForKey:
, который похож на это:
NSNumber *storedNumber = dictionary[@"magicNumber"]; |
Переменчивость
Если необходимо добавить или удалить объекты из словаря после создания, необходимо использовать NSMutableDictionary
подкласс, как это:
[dictionary setObject:@"another string" forKey:@"secondString"]; |
[dictionary removeObjectForKey:@"anObject"]; |
Представляйте ноль с NSNull
Не возможно добавить nil
к классам набора, описанным в этом разделе, потому что nil
в Objective C не означает “объекта”. Если Вы не должны представлять “объект” в наборе, можно использовать NSNull
класс:
NSArray *array = @[ @"string", @42, [NSNull null] ]; |
NSNull
singleton-класс, что означает что null
метод будет всегда возвращать тот же экземпляр. Это означает, что можно проверить, равен ли объект в массиве совместно используемому NSNull
экземпляр:
for (id object in array) { |
if (object == [NSNull null]) { |
NSLog(@"Found a null object"); |
} |
} |
Используйте наборы для сохранения графа объектов
NSArray
и NSDictionary
классы упрощают писать свое содержание непосредственно в диск, как это:
NSURL *fileURL = ... |
NSArray *array = @[@"first", @"second", @"third"]; |
BOOL success = [array writeToURL:fileURL atomically:YES]; |
if (!success) { |
// an error occured... |
} |
Если каждый содержащий в нем объект является одним из типов списка свойств (NSArray
, NSDictionary
, NSString
, NSData
, NSDate
и NSNumber
), возможно воссоздать всю иерархию от диска, как это:
NSURL *fileURL = ... |
NSArray *array = [NSArray arrayWithContentsOfURL:fileURL]; |
if (!array) { |
// an error occurred... |
} |
Для получения дополнительной информации о списках свойств см. Руководство по программированию Списка свойств.
Если необходимо сохранить другие типы объектов, чем просто стандартные классы списка свойств, показанные выше, можно использовать объект archiver, такой как NSKeyedArchiver
, создать архив собранных объектов.
Единственное требование для создания архива - то, что каждый объект должен поддерживать NSCoding
протокол. Это означает, что каждый объект должен знать, как закодировать себя к архиву (путем реализации encodeWithCoder:
метод), и декодируют себя, когда считано из существующего архива ( initWithCoder:
метод).
NSArray
, NSSet
и NSDictionary
классы, и их непостоянные подклассы, вся поддержка NSCoding
, что означает, что можно сохранить сложные иерархии объектов с помощью archiver. При использовании Интерфейсного Разработчика для разметки окон и представлений, например, получающийся файл пера является просто архивом иерархии объектов, которую Вы создали визуально. Во время выполнения файл пера разархивирован к иерархии объектов с помощью соответствующих классов.
Для получения дополнительной информации об Архивах см. Руководство по программированию Архивов и Сериализации.
Используйте самые эффективные методы перечисления набора
Objective C и Касание Какао или Какао предлагают множество способов перечислить содержание набора. Несмотря на то, что возможно использовать традиционный C for
цикл для итерации по содержанию, как это:
int count = [array count]; |
for (int index = 0; index < count; index++) { |
id eachObject = [array objectAtIndex:index]; |
... |
} |
это - наиболее успешная практика для использования одного из других методов, описанных в этом разделе.
Быстрое перечисление упрощает перечислять набор
Много классов набора соответствуют NSFastEnumeration
протокол, включая NSArray
, NSSet
и NSDictionary
. Это означает, что можно использовать быстрое перечисление, функцию уровня языка Objective C.
Быстрый синтаксис перечисления, чтобы перечислить содержание массива или установить похож на это:
for (<Type> <variable> in <collection>) { |
... |
} |
Как пример, Вы могли бы использовать быстрое перечисление для журналирования описания каждого объекта в массиве, как это:
for (id eachObject in array) { |
NSLog(@"Object: %@", eachObject); |
} |
eachObject
переменная установлена автоматически в текущий объект для каждого, проходят через цикл, таким образом, один оператор журнала появляется на объект.
При использовании быстрого перечисления со словарем Вы выполняете итерации по ключам словаря, как это:
for (NSString *eachKey in dictionary) { |
id object = dictionary[eachKey]; |
NSLog(@"Object: %@ for key: %@", object, eachKey); |
} |
Быстрое перечисление ведет себя во многом как стандарт C for
цикл, таким образом, можно использовать break
ключевое слово для прерывания итерации, или continue
совершенствоваться к следующему элементу.
При перечислении упорядоченного набора перечисление продолжается в том порядке. Для NSArray
, это означает, что первая передача будет для объекта в индексе 0
, второе для объекта в индексе 1
, и т.д. Если необходимо отслеживать текущий индекс, просто считать итерации, поскольку они происходят:
int index = 0; |
for (id eachObject in array) { |
NSLog(@"Object at index %i is: %@", index, eachObject); |
index++; |
} |
Даже если набор является непостоянным, Вы не можете видоизменить набор во время быстрого перечисления. При попытке добавить или удалить собранный объект из цикла, то Вы генерируете исключение на этапе выполнения.
Большинство наборов также поддерживает объекты перечислителя
Также возможно перечислить многих Какао и Сенсорные наборы Какао при помощи NSEnumerator
объект.
Можно спросить NSArray
, например, для objectEnumerator
или a reverseObjectEnumerator
. Возможно использовать эти объекты с быстрым перечислением, как это:
for (id eachObject in [array reverseObjectEnumerator]) { |
... |
} |
В этом примере цикл выполнит итерации по собранным объектам в обратном порядке, таким образом, последний объект будет первым и т.д.
Также возможно выполнить итерации через содержание путем вызова перечислителя nextObject
метод неоднократно, как это:
id eachObject; |
while ( (eachObject = [enumerator nextObject]) ) { |
NSLog(@"Current object is: %@", eachObject); |
} |
В этом примере, a while
цикл используется для установки eachObject
переменная к следующему объекту для каждого проходит через цикл. Когда больше нет оставленных объектов, nextObject
метод возвратится nil
, который оценивает как логическое значение лжи так остановки цикла.
Как с быстрым перечислением, Вы не можете видоизменить набор при перечислении. И, поскольку Вы могли бы собрать из имени, это быстрее для использования быстрого перечисления, чем использовать объект перечислителя вручную.
Много наборов основанное на опорном блоке перечисление
Также возможно перечислить NSArray
, NSSet
и NSDictionary
использование блоков. Блоки покрыты подробно в следующей главе.