Ссылка представляет собой именно то, что вы себе представляете, — способ выбора некоторой определенной отдельной сущности. Особенно хороший вид ссылки — имя.

Если мы хотим обратиться к Сократу, то утомительно каждый раз описывать его как “толстый лысый парень, который вечно задает дурацкие вопросы”. Куда проще указать его по имени — “Сократ”. Переменная языка программирования С представляет собой эквивалент имени. Присваивание некоторого значения переменной приводит к тому, что данная переменная (то есть имя) становится ссылкой на это значение.

В языке программирования С каждая переменная должна быть объявлена как имеющая некоторый тип данных. В языке С очень немного фундаментальных типов данных. Эти типы определенно не готовы к роли объектных типов. Для того чтобы добавить к С объекты и тем самым превратить С в объектно-ориентированный язык С, Objective-C использует гибкость указателей С (см. главу 1). Указатель представляет собой тип данных С, но при этом он может указывать на все, что угодно. Таким образом, в Objective-C каждая ссылка на объект является указателем (и Objective-C сам заботится о выяснении, на что этот указатель указывает).

Тот факт, что ссылки на объекты в Objective-C являются указателями, особенно очевидно в случае ссылки на экземпляр (см. главу 2). В объектно-ориентированном языке, таком как Objective-C, типом экземпляра является его класс. Таким образом, хотелось бы использовать в Objective-C имя класса так, как в С мы используем имя любого типа данных. И позволяют это сделать именно указатели. С одной стороны, указатели удовлетворяют требованию С о том, что ссылка должна быть некоторым определенным типом данных С, а с другой стороны — требованию Objective-C о том, что мы должны иметь возможность указать любой тип класса из огромного их множества. Если в Objective-C переменная явно ссылается на экземпляр класса MyClass, то она имеет тип MyClass*, т.е. является указателем на MyClass. В общем случае в Objective-C ссылка на экземпляр класса является указателем, а имя типа данных, на который указывает этот указатель, представляет собой имя класса этого экземпляра.

 

Обратите внимание на соглашение об использовании прописных букв. Обычно имена переменных начинаются со строчной бухвы, а имена классов - с прописной.

 

Как упоминалось в главе 1, тот факт, что в Objective-C ссылка на экземпляр является указателем, обычно не вызывает каких-либо трудностей, так как указатели последовательно используются везде в языке. Например, сообщение, направленное экземпляру, отправляется указателю, так что нет необходимости в разыменовании последнего. Действительно, установив, что переменная, представляющая экземпляр, является указателем, можно забыть об этом факте и просто непосредственно работать с этой переменной:

NSString* s = @"Hello, world!";
NSString* s2 = [s uppercaseString];

Один раз установив, что переменная s имеет тип NSString*, вы больше никогда не будете разыменовывать s (т.е. никогда не будет говорить о *s) для доступа к “реальным” строкам NSString. Так что все выглядит так, как будто указатель является реальным типом NSString. Таким образом, в предыдущем примере, после того как переменная s была объявлена как указатель на объект класса NSString, сообщение uppercaseString отправляется непосредственно этой переменной. (Сообщение uppercaseString запрашивает у NSString создание и возвращение версии хранимой объектом строки в верхнем регистре; таким образом, после выполнения приведенного кода s2 представляет собой строку @"HELLO, WORLD! ".)

Связь между указателем, экземпляром и классом этого экземпляра столь тесная, что вполне естественно говорить о выражении наподобие MyClass* как об означающем “экземпляр MyClass”, а о значении MyClass* как о “MyClass”. Программист на языке Objective-C, говоря о приведенном выше примере, просто сказал бы, что s представляет собой NSString, что uppercaseString возвращает NSString и так далее. Это прекрасно, что можно так говорить, и я постоянно делаю это сам — надо только помнить, что это просто в определенном смысле сокращение. Такое выражение на самом деле означает “экземпляр NSString”, что, в свою очередь, означает, что поскольку экземпляр представлен в виде указателя С, то он является не чем иным, как NSString*, т.е. указателем на NSString.

Хотя тот факт, что ссылки на экземпляры в Objective-C являются указателями, не вызывает каких-либо особых трудностей, вы все равно должны осознавать, что такое указатели и как они работают. Как я подчеркивал в главе 1, когда вы работаете с указателями, ваши действия имеют особый смысл. Так что вот некоторые основные факты об указателях, которые вам следует иметь в виду при работе со ссылками на экземпляры в Objective-C.

Распространенная ошибка начинающего — забыть о звездочке в объявлении экземпляра, на что компилятор позже отреагирует загадочными сообщениями типа “Interface type cannot be statically allocated”.


 

 

 

Добавить комментарий