Используя значения

NSValue объект является простым контейнером для единственного C или элемента данных Objective C. Это может содержать любой из скалярных типов такой как int, float, и char, а также указатели, структуры и объект ids. Цель этого класса состоит в том, чтобы позволить элементам таких типов данных быть добавленными к объектам коллекции, таким как экземпляры NSArray или NSSet, которые требуют, чтобы их элементы были объектами. NSValue объекты являются всегда неизменными.

Создать NSValue объект с определенным элементом данных, Вы обеспечиваете указатель на элемент вместе со струной до, описывающей тип элемента в кодировании типа Objective C. Вы получаете эту строку с помощью @encode() директива компилятора, возвращающая специфичное для платформы кодирование для данного типа (см. Кодировки Типа для получения дополнительной информации о @encode() и список кодов типа). Например, эта выборка кода создает theValue, содержащий NSRange:

NSRange myRange = {4, 10};
NSValue *theValue = [NSValue valueWithBytes:&myRange objCType:@encode(NSRange)];

Следующий пример иллюстрирует кодирование пользовательской структуры C.

// assume ImaginaryNumber defined:
typedef struct {
    float real;
    float imaginary;
} ImaginaryNumber;
 
 
ImaginaryNumber miNumber;
miNumber.real = 1.1;
miNumber.imaginary = 1.41;
 
NSValue *miValue = [NSValue valueWithBytes: &miNumber
                            withObjCType:@encode(ImaginaryNumber)];
 
ImaginaryNumber miNumber2;
[miValue getValue:&miNumber2];

Тип, который Вы указываете, должен иметь постоянную длину. Вы не можете сохранить струны до, массивы переменной длины и структуры и другие типы данных неопределенной длины в NSValue— необходимо использовать NSString или NSData объекты для этих типов. Можно сохранить указатель на элемент переменной длины в NSValue объект. Следующая выборка кода неправильно пытается поместить струну до непосредственно в NSValue объект:

/* INCORRECT! */
char *myCString = "This is a string.";
NSValue *theValue = [NSValue valueWithBytes:myCString withObjCType:@encode(char *)];

В этой выборке кода содержание myCString интерпретируется как указатель на a char, таким образом, первые четыре байта, содержавшиеся в строке, обрабатываются как указатель (фактическое число используемых байтов может меняться в зависимости от аппаратной архитектуры). Т.е. последовательность, «Это» интерпретируется как значение указателя, которое вряд ли будет юридическим адресом. Корректный способ сохранить такой элемент данных состоит в том, чтобы использовать NSString объект (если необходимо содержать символы в объекте), или передать адрес его указателя, не самого указателя:

/* Correct. */
char *myCString = "This is a string.";
NSValue *theValue = [NSValue valueWithBytes:&myCString withObjCType:@encode(char **)];

Здесь адрес myCString передается (&myCString), таким образом, адрес первого символа строки сохранен в theValue.