Почему бы мне не объявить NSInteger с * - PullRequest
42 голосов
/ 18 июня 2009

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

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

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

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

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

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

Ответы [ 5 ]

68 голосов
/ 18 июня 2009

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

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

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

NSInteger processID = [[NSProcessInfo processInfo] processIdentifier];

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

NSInteger *pointerToProcessID = &processID;

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

25 голосов
/ 18 июня 2009

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

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

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

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

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

3 голосов
/ 18 июня 2009

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

2 голосов
/ 18 июня 2009

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

0 голосов
/ 01 мая 2019

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

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
...