#objective-c #object #pointers #syntax
#objective-c #объект #указатели #синтаксис
Вопрос:
В этом фрагменте:
NSString *testString;
testString = [[NSString alloc] init];
Почему во второй строке нам не нужно писать *testString = ...
, чтобы получить доступ к местоположению, на которое оно фактически указывает?
После первой строки, что такое *testString
и что такое testString
?
Ответ №1:
В первой строке вы создаете указатель типа NSString. Указатели в C и Objective-C обозначаются символом звездочки (*) при их объявлении. Вторая строка, в которой вы говорите, что этот указатель с именем «testString» ссылается на ячейку памяти объекта NSString, который вы выделили в памяти.
Ответ №2:
На все объекты ссылаются указатели. Первая строка
NSString * testString;
объявляет переменную экземпляра. Если ваш тип переменной является объектом (помимо идентификатора типа), вам необходимо *
с этого момента ссылка на testString является указателем
Если вы создаете 2 строки. создаются 2 физических объекта (в памяти)
NSString * testString = [[NSString alloc] init];
NSString * testString2 = [[NSString alloc] init];
//setting testString to testString2 will lose the pointer to testString for good
testString = testString2; //<--bad if you still care about testString (and leaks the memory too)
Я рекомендую ознакомиться с руководством Apple по Objective-C. В частности, этот раздел
Ответ №3:
Почему во второй строке нам не нужно писать
*testString = ...
, чтобы получить доступ к местоположению, на которое оно фактически указывает?
init
Метод возвращает универсальный указатель на объект — его возвращаемый тип id
. testString
является указателем на NSString
, который является объектом, поэтому вы присваиваете указатель другому указателю. Разыменование присвоенного указателя будет несоответствием типа.
Имя переменной — это место (метка для адреса памяти), в которое что-то помещается. Тип переменной — это то, что вы можете туда поместить. В случае указателя то, что вы в него помещаете, также является адресом памяти. Чтобы получить этот адрес, вы разыменовываете указатель. То, что вы можете поместить по этому адресу, отличается от того, что вы помещаете в сам указатель.
После первой строки, что такое
*testString
и что такоеtestString
?
После первой строки, *testString
, или то, на что testString
указывает, является мусором (фактически неопределенным). testString
является указателем (4 или 8 байт в зависимости от вашей системы) на адрес в памяти, и он также не определен.
После второй строки *testString
находится NSString
объект. testString
по-прежнему является указателем на адрес, где есть допустимый NSString
объект.
Ответ №4:
Это просто потому, что мы влияем на указатель.
[[NSString alloc] init]
возвращает указатель на NSString.
В Cocoa каждый объект выделяется динамически (как malloc
в C), и каждый NSObject
обрабатывается через его указатель / адрес (в такой степени, что многие программисты ObjC даже не знают, что они манипулируют указателями, а не объектами)