Вопрос

Я пробую свои силы на курсе iPhone из Стэнфорда на iTunes U, и меня немного смущают указатели. В первом задании я пытался сделать что-то вроде этого

NSString *processName = [[NSProcessInfo processInfo] processName];
NSInteger *processID = [[NSProcessInfo processInfo] processIdentifier];

В результате возникла ошибка, после вслепую я обнаружил, что именно * в строке NSInteger и была причиной проблемы.

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

  

В отличие от веб-разработки, мне сейчас нужно   беспокоиться о памяти, ну, в большей степени, чем в веб-разработке. Итак, когда я   создать переменную, она получает   немного памяти где-то (RAM я   предполагать). Вместо прохождения   переменная вокруг, я передаю указатель на   этот кусок памяти вокруг. А также   указатели объявляются с префиксом   имя переменной с *.

Предполагая, что я прав, меня озадачивает, почему мне не нужно делать это для NSInteger?

Это было полезно?

Решение

NSInteger - это примитивный тип, что означает, что он может храниться локально в стеке . Вам не нужно использовать указатель для доступа к нему, но вы можете, если хотите. Строка:

NSInteger *processID = [[NSProcessInfo processInfo] processIdentifier];

возвращает фактическую переменную, а не ее адрес. Чтобы это исправить, вам нужно удалить * :

NSInteger processID = [[NSProcessInfo processInfo] processIdentifier];

У вас может быть указатель на NSInteger , если он действительно нужен:

NSInteger *pointerToProcessID = &processID;

Амперсанд - это адрес оператора. Он устанавливает указатель на NSInteger , равный адресу переменной в памяти, а не целому числу в переменной.

Другие советы

Причина, по которой вы не объявляете NSInteger с * , заключается в том, что это не объект. NSInteger - это просто int или long :

#if __LP64__
typedef long NSInteger;
#else
typedef int NSInteger;
endif

Если он используется в 32-разрядном приложении, это 32-разрядное целое число, а если оно встроено в 64-разрядное приложение, это 64-разрядное целое число.

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

Объекты, с другой стороны, могут быть переданы другим функциям только в качестве указателей. Это связано с тем, что для объектов динамически выделяется память, и поэтому они не могут быть объявлены в стеке. Поскольку для int или long для них выделено фиксированное количество памяти, это не проблема.

* означает & # 8220; указатель & # 8221 ;. Переменная объекта содержит указатель на объект, поэтому она имеет * ; переменная NSInteger содержит NSInteger, а не указатель на NSInteger, поэтому она не имеет * . Помещение * в эту переменную дает вам как минимум предупреждение, потому что вы помещаете целое число в переменную-указатель.

NSInteger - просто определение типа для int, AFAIK.

Работа с указателями

NSInteger integer1 = 1;
NSLog(@"1. integer1:%ld &integer1:%p", integer1, &integer1);
//1. integer1:1 &integer1:0x7ffee59e8a98

NSInteger *integer2 = &integer1;
NSLog(@"2. integer2:%p &integer2:%p *integer2:%ld", integer2, &integer2, *integer2);
//2. integer2:0x7ffee59e8a98 &integer2:0x7ffee59e8a90 *integer2:1

*integer2 = 2;
NSLog(@"3. integer2:%p &integer2:%p *integer2:%ld \t integer1:%ld &integer1:%p", integer2, &integer2, *integer2, integer1, &integer1);
//3. integer2:0x7ffee59e8a98 &integer2:0x7ffee59e8a90 *integer2:2    integer1:2 &integer1:0x7ffee59e8a98
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top