Указатели переменных экземпляра Objective C - PullRequest
9 голосов
/ 28 мая 2009

Я новичок в цели C, и я просто хотел получить общее разъяснение о том, когда использовать указатель, а когда нет, при объявлении переменных экземпляра.

Пример, который я могу вспомнить, это UIView против BOOL. UIView Я бы сделал указатель, BOOL я бы не стал (потому что компилятор кричал на меня).

Любое общее руководство было бы замечательно.

Приветствия

Ответы [ 3 ]

20 голосов
/ 28 мая 2009

Если это объект, вы используете обозначение указателя. Все типы c (int, BOOL, long и т. Д.) Не являются объектами, и поэтому вы используете указатель только в том случае, если вы хотите указатель на их расположение в памяти:

NSObject *obj;
UIView<Protocol> *obj;
int integerVar;
BOOL isTrue;

Особый случай - id, который сам по себе является указателем на объект, поэтому вам не нужно *:

id obj;

Немного сложно:

NSInteger int;
NSNumber *number;

NSInteger - это соответствующий тип int для платформы, тогда как NSNumber - это объект, который может содержать int, float или что-то еще.

5 голосов
/ 28 мая 2009

Указатели используются для хранения адреса выделенной памяти. Когда вы создаете объект в какао, вы выделяете память и сохраняете адрес в указателе.

BOOL, char, int сохранить значение.

Когда вы создаете класс, alloc выделяет память, поэтому вам нужно сохранить указатель на эту память, чтобы иметь к нему доступ:

NSMutableArray * arr = [[NSMutableArray alloc] init];

Как очистить типы C из памяти?

Простые типы размещаются в стеке. Когда метод вызывается, в стеке выделяется пространство для хранения всех переменных метода (плюс некоторые другие вещи, такие как параметры, адрес возврата и т. Д.). Так что стек растет. Как только метод возвращает сжатый стек, и пространство, которое использовалось методом, теперь освобождается - так что да, простые типы будут «очищены».

На самом деле все гораздо проще, чем кажется. Загляните в Википедия. В стек - раздел Аппаратные стеки , чтобы узнать больше, чтобы удовлетворить ваше любопытство.

Когда вы «выделяете память», эта память выделяется в куче. Куча есть для всего исполнения вашего приложения. Как только вы распределяете память в куче, вы получаете адрес этой памяти - вы сохраняете этот адрес в указателях. Указатель - это просто переменная, в которой хранится адрес памяти.

Когда ваш метод возвращает, у вас больше нет доступа к вашим «простым» переменным, объявленным в методе (например, BOOL, int, char и т. Д.), Но память в куче все еще там. Если у вас все еще есть адрес памяти (например, указатель), вы можете получить к нему доступ.

А как насчет переменных экземпляра «простого» типа (edit: inside object?)?

Когда вы создаете объект (мы говорим о цели C и Какао здесь) и выделяете его, вы выделяете пространство для всего объекта. Размер объекта - это размер всех его переменных (не уверен, добавляет ли obj-c другие вещи). Таким образом, переменные экземпляра являются частью памяти вашего объекта в куче. Когда вы отпускаете / удаляете объект, его память освобождается, и у вас больше нет доступа к переменным, которые хранятся внутри объекта (в obj-c вы вызываете release, каждый объект сохраняет счетчик ссылок, когда счетчик ссылок достигает 0, объект освобождается - память на кучу восстанавливается).

1 голос
/ 28 мая 2009

Каждый класс Objective C, такой как NSString, NSObject, NSView и т. Д., Должен быть указателем, за исключением нескольких специальных типов, таких как NSUInteger, который, как я верю, является просто определением типа для int.

NSString *stringyString = @"THIS STRING IS STRINGY!!!11";
NSOpenPanel *openPanel;
NSObject *objectyObject;
NSUInteger integeryInteger = 7;

Единственное, что не будет, это id, потому что это указатель на любой объект.

id pointerThatCanBeSetToAnyObject = [NSString stringWithString:@"HEYYYY"];

Только для типов переменных C, таких как int, float, BOOL и т. Д., Указатель не требуется, за исключением строк C, таких как массивы char.

int SEVEN = 7;
float SIXPOINTTWO = 6.2;
char *characterArray = "HEYYYYY";

Наконец, классы CoreFoundation имеют своего рода гибрид; многие классы будут указателями, но для некоторых классов, таких как CFString, CFStringRef уже будет указателем. Многие функции CFString возвращаются как CFStringRef. CFString * и CFStringRef взаимозаменяемы с NSString * (это называется бесплатным мостовым соединением), хотя компилятор, вероятно, оценит это, если вы приведете его первым.

CFString *veryStringyString = @"STRINGYNESS!!11!one";
CFStringRef especiallyStringyString = @"STRRRRRRINNNNNGGGGYYYYY";
NSString *STRINGYNESS = (NSString *)veryStringyString;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...