Подтвердить что ты не робот

Почему я не объявляю NSInteger с *

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

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

Сгенерировав ошибку, после слепого слепого, я обнаружил, что именно в строке NSInteger возникла проблема.

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

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

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

4b9b3361

Ответ 1

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

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

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

NSInteger processID = [[NSProcessInfo processInfo] processIdentifier];

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

NSInteger *pointerToProcessID = &processID;

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

Ответ 2

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

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

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

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

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

Ответ 3

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

Ответ 4

NSInteger - это просто typedef для int, AFAIK.

Ответ 5

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

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