Чтение онлайн

на главную - закладки

Жанры

Программирование на Objective-C 2.0
Шрифт:

После выделения памяти для нового объекта класса Fraction в него копиру-ются переменные получателя numerator и denominator. Предполагается, что метод copyWithZone: будет возвращать новую копию объекта, которую вы создаете в своем методе.

Этот новый метод проверяется в профамме 18.3. // Копирование дробей #import "Fraction.h" Jfimport <Foundation/NSAutoreleasePool.h> int main (int arge, char *argv[]) { NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; Fraction *11 = [[Fraction alloc] init]; Fraction *f2; [ft setTo: 2 over: 5]; f2 = [fl copy]; [!2 setTo: 1 over: 3]; [fl print]; [12 print]; [fl release]; [f2 release]; [pool drain]; return 0; }

Вывод программы 18.3 2/5 1/3

Эта программа создает объект класса Fraction с именем fl и присваивает ему значение 2/5. Затем вызывается метод сору для создания копии, который передает сообщение copyWrthZone: этому объекту. Этот метод создает новый объект класса Fraction, копирует в него значения из 11 и возвращает результат. После воз-врата в main этот результат присваивается 12. Последующее присваивание 12 дро-би 1/3 подтверждает, что это не оказывает влияния на исходную дробь 11. Изме-ните строку программы 12 = [И сору];

на 12 = 11;

и удалите высвобождение (release) 12 в конце программы, после чего увидите другие результаты.

Если ваш класс может быть подклассом, то метод copyWithZone: будет насле-доваться. В таком случае вы должны изменить строку этого метода Fraction *newFract = [[Fraction allocWithZone: zone] init]; на строку Fraction *newFract = [[[self class] allocWithZone: zone] init];

Это позволяет выделить память для нового объекта изданного класса, кото-рый является получателем копии. (Например, если это подкласс с именем NewFraction, то нужно выделить в наследуемом методе память для нового объекта NewFraction вместо объекта Fraction.)

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

Вы должны решить, какое копирование нужно реализовать в вашем классе: поверхностное или глубокое. Задокументируйте это для других пользователей вашего класса. 18.4. Копирование объектов в методах-установщиках и методах-получателях

Каждый раз, реализуя метод-установщик (setter) или метод-получатель (getter), вы должны продумать, что будет сохраняться в переменных экземпляра, что будет считываться и нужно ли защитить эти значения. Рассмотрим оператор, в котором мы задаем имя одного из объектов AddressCard с помощью метода setName: [newCard setName: newName];

Предположим, что newName — это строковый объект, содержащий имя новой карточки. Предположим также, что внутри процедуры установщика мы просто присваиваем параметр соответствующей переменной экземпляра. -(void) setName: (NSString *) theName { name = theName; }

Если затем в программе будут изменены некоторые символы, содержащиеся в newName, то одновременно будет изменено соответствующее поле адресной карточки, поскольку это ссылка на один и тот же строковый объект.

Чтобы исключить этот побочный эффект, следует создать копию объекта в процедуре установщика. С помощью метода alloc мы создали новый строковый объект и затем с помощью метода initWithString: присвоили ему значение пара-метра, передаваемого методу.

Можно также написать версию метода setName:, чтобы использовать сору, например -(void) setName: (NSString *) theName { name = [theName copy];}

Чтобы управлять памятью в процедуре установщика было удобно, необхо-димо сначала автоматически высвободить (autorelease) старое значение, как показано ниже. -(void) setName: (NSString *) theName { [name autorelease]; name = [theName copy]; }

Если задать атрибут copy в объявлении свойств (property) для переменной экземпляра, то в синтезируемом методе будет использоваться метод класса сору (написанный вами или унаследованный). Поэтому объявление @property (nonatomic, copy) NSString *name;

приведет к созданию синтезируемого метода, который действует следующим образом. -(void) setName: (NSString *) theName { if (theName != name) { [name release] name = [theName copy]; } }

Атрибут nonatomic указывает системе, что в данном случае не нужно защи-щать методы доступа с помощью блокировки mutex (mutually exclusive — взаимоисключение). При написании кода с защитой потоков используются блокировки mutex, чтобы исключить одновременное выполнение одного кода двумя потоками (ситуация, которая часто вызывает ужасные проблемы). Но эти блокировки могут замедлять выполнение программ, поэтому вы можете отказаться от них, если знаете, что этот код будет всегда выполняться только в одном потоке.

Если атрибут nonatomic не указан или вместо него указан атрибут atomic (это атрибут по умолчанию), то переменная экземпляра будет защищена блокировкой mutex. Кроме того, синтезируемый метод-получатель будет удерживать (retain) и автоматически высвобождать (autorelease) переменную экземпляра перед тем, как будет возвращено ее значение. В среде без сборки мусора это защищает переменную экземпляра от возможной перезаписи методом-установщиком, который высвобождает старое значение переменной экземпляра, прежде чем установить новое значение. Использование retain в методе-получателе гарантирует, чтобы память для старого значения не будет освобождена.

Примечание. Проблема высвобождения и автоматического высвобождения (retain/autorelease) не актуальна в среде со сборкой мусора, в которой вызовы этих методов игнорируются, но это не относится к блокировке mutex. Если ваш код будет выполняться в многопотоковой среде, предусмотрите использование методов доступа с атрибутом atomic,.

То же самое можно сказать о защите значения переменных экземпляра в процедурах получателей. Если в такой процедуре возвращается объект, то вы должны обеспечить, чтобы изменения, вносимые в возвращаемое значение, не повлияли на значение ваших переменных экземпляра. В таких случаях можно создать копию переменной экземпляра и возвращать эту копию.

Поделиться:
Популярные книги

Я Гордый часть 2

Машуков Тимур
2. Стальные яйца
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Я Гордый часть 2

Геном хищника. Книга третья

Гарцевич Евгений Александрович
3. Я - Легенда!
Фантастика:
боевая фантастика
рпг
попаданцы
5.00
рейтинг книги
Геном хищника. Книга третья

Как я строил магическую империю

Зубов Константин
1. Как я строил магическую империю
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Как я строил магическую империю

Цвет

Васильев Сергей Викторович
Фантастика:
научная фантастика
5.00
рейтинг книги
Цвет

Бастард Императора. Том 2

Орлов Андрей Юрьевич
2. Бастард Императора
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Бастард Императора. Том 2

Мастер 10

Чащин Валерий
10. Мастер
Фантастика:
боевая фантастика
попаданцы
аниме
5.00
рейтинг книги
Мастер 10

Чехов. Книга 2

Гоблин (MeXXanik)
2. Адвокат Чехов
Фантастика:
фэнтези
альтернативная история
аниме
5.00
рейтинг книги
Чехов. Книга 2

Московское золото или нежная попа комсомолки. Часть Вторая

Хренов Алексей
2. Летчик Леха
Фантастика:
попаданцы
5.00
рейтинг книги
Московское золото или нежная попа комсомолки. Часть Вторая

Кодекс Охотника. Книга XVIII

Винокуров Юрий
18. Кодекс Охотника
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Кодекс Охотника. Книга XVIII

Барон нарушает правила

Ренгач Евгений
3. Закон сильного
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Барон нарушает правила

Имперец. Том 5

Романов Михаил Яковлевич
4. Имперец
Фантастика:
попаданцы
альтернативная история
аниме
6.00
рейтинг книги
Имперец. Том 5

Виконт. Книга 2. Обретение силы

Юллем Евгений
2. Псевдоним `Испанец`
Фантастика:
боевая фантастика
попаданцы
рпг
7.10
рейтинг книги
Виконт. Книга 2. Обретение силы

Эмблема

Поселягин Владимир Геннадьевич
2. Целитель
Фантастика:
технофэнтези
фэнтези
5.00
рейтинг книги
Эмблема

Проблемы роста

Meijin Q
Проза:
современная проза
повесть
5.00
рейтинг книги
Проблемы роста