Эта глава в основном сконцентрирована на механике создания экземпляра. Однако зачастую ваш код будет связан не с созданием нового экземпляра, а со ссылкой на экземпляр, который уже существует.

На экземпляр можно ссылаться либо с использованием имени ссылки на объект, которой он был ранее присвоен (это может быть переменная экземпляра), либо получая его как результат вызова метода — и никак иначе. Если у вас еще нет именованной ссылки на некоторый экземпляр (в виде переменной или переменной экземпляра), то нужный экземпляр может вернуть вызов метода. Например, вот как вы запрашиваете последний эле-мент массива (NSArray):

id myThing = [myArray lastObject];

Массив myArray типа NSArray не создает объект, который передает вам. Этот объект уже существует; myArray просто содержал указатель на него. Теперь он поделился этим объектом с вами, только и всего.

Аналогично многие классы могут обходиться одним создаваемым объектом. Например, ваше приложение имеет ровно один экземпляр класса UIApplication (мы называем такой экземпляр синглтоном); для доступа к нему надо отправить сообщение sharedApplication классу UIApplication:

 

UIApplication* theApp = [UIApplication sharedApplication];

 

Экземпляр этого синглтона существует еще до обращения к нему; фактически он существует еще до начала выполнения вашего кода. Вам не надо заботиться о его создании; все, что вам надо знать, — что вы можете сохранить его, когда захотите. Несколько подробнее о глобально доступных синглтонах речь пойдет в главе 13.

В обоих примерах код решает две задачи: найти способ указать уже существующий экземпляр и присвоить этот существующий экземпляр переменной, тем самым создавая (не новый экземпляр, но) новое имя, с помощью которого можно обращаться к уже существующему экземпляру. Это две стороны одной медали — ссылки на экземпляр.

Задача ссылки на экземпляр — это то, с чем вы постоянно имеете дело при программировании для iOS. Этот вопрос может показаться тривиальным, но на самом деле это не так. В действительности задача ссылки на уже существующий экземпляр является настолько важной, что я посвящаю ей большую часть главы 13. Экземпляр не имеет смысла, если к нему нельзя обратиться. Если вы не можете ссылаться на экземпляр, ему нельзя отправить сообщение. Если вы не можете ссылаться на экземпляр, его нельзя использовать в качестве аргумента в вызове метода. Если вы не можете ссылаться на экземпляр, нельзя ни получить информацию о нем, ни сделать с ним что-нибудь. Довольно часто бывают ситуации, когда вы знаете, что экземпляр существует, но, чтобы обратиться к нему, приходится попотеть. Возможно, вам даже придется переписать или заново спроектировать всю вашу программу, меняя порядок событий в программе, чтобы иметь возможность получить ссылку на конкретный экземпляр в тот момент, когда она вам понадобится.

Кроме того, после того как вы получите ссылку на желаемый экземпляр, может понадобиться ее сохранить. В случае синглтона, такого, как [UIApplication sharedApplication], это не является проблемой. Существует только один разделяемый экземпляр приложения, и класс UIApplication будет рад предоставить его вам снова и снова, всякий раз, когда вы попросите его об этом. Таким образом, его можно хранить, просто используя в соответствующих местах вашей программы выражение [UIApplication sharedApplication], и вы, вероятно, так и будете поступать. Присвоение разделяемого экземпляра приложения своей переменной, как, например, переменной theApp в предыдущем примере, — не более чем вопрос удобства. Это короткое простое имя для того же самого экземпляра.

Но все совсем не так в случае экземпляра [myArray lastObject]. Здесь мы уже имеем ссылку на массив (myArray) и теперь озабочены получением ссылки на один из его элементов, а именно на последний элемент. Экземпляр, который в настоящее время функционирует в качестве последнего элемента массива myArray, может не всегда быть последним элементом myArray. Он даже не всегда может быть элементом myArray. На самом деле массив myArray может сам прекратить существование. Если конкретный экземпляр, на который в настоящее время мы можем сослаться как [myArray lastOb j ect ], будет иметь важное значение для нас в будущем, нам может потребоваться принять меры для поддержания некоторых других ссылок на него, которые не зависят от статуса или состояния некоторого массива.

Это основная причина для присваивания экземпляра, возвращаемого вызовом [myArray lastObject], переменной myThing. Теперь, независимо от того, что происходит в массиве, имя myThing будет продолжать ссылаться на указанный экземпляр.

В предыдущем коде myThing — просто локальная автоматическая переменная; эта переменная выйдет из области видимости, когда та закончится (например, когда завершится выполнение текущего метода), и возможность сослаться на этот экземпляр будет потеряна. Что мы можем поделать с этим? Все это происходит в пределах кода некоторого класса, выполняемого в рамках некоторого экземпляра; скажем, это экземпляр класса Dog. Если нам требуется экземпляр myThing, продолжительность жизни которого соответствует времени жизни экземпляра Dog, мы можем присвоить это значение переменной экземпляра. Такой поступок имеет дополнительное преимущество: после этого к нему смогут обращаться другие методы экземпляра данного экземпляра Dog! Более того, если имеется метод доступа, другие объекты, имеющие ссылку на наш экземпляр Dog, будут иметь ссылку и на экземпляр myThing также! Так мы можем управлять временем жизни экземпляра, обеспечивая при этом возможность получить ссылку на него в нужный нам момент в будущем. Это настолько важная возможность, что зачастую именно она оказывается главной причиной для наличия в классе переменных экземпляров.


 

 

 

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