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

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

Жанры

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

Вывод программы 8.5 Origin at (Координаты начала) (100, 200) Origin at (50, 50)

В этой программе значение объекта myPoint было изменено с (100, 200) на (50, 50), то есть были изменены координаты начала прямоугольника. Но почему это произошло? Здесь не было явным образом задано новое значение начала прямоугольника, почему оно изменилось? Вернемся к определению метода setOrigin:, чтобы понять причину: -(void) setOrigin: (XYPoint *) pt { origin = pt; }

При вызове метода setOrigin: с помощью выражения myRect.origin = myPoint;

значение myPoint передается этому методу как аргумент. Это значение указывает место

в памяти, где хранится данный объект XYPoint (рис. 8.5).

Рис. 8.5. Объект myPoint класса XYPoint в памяти

Это значение, сохраненное в myPoint и являющееся указателем места в памяти, копируется в локальную переменную pt, определенную внутри метода. После этого pt и myPoint являются ссылкой на одни и те же данные, хранящиеся в памяти (рис. 8.6).

Рис. 8.6. Передача методу информации о начале прямоугольника

Когда переменной origin присваивается pt внутри этого метода, указатель, хранящийся внутри pt, копируется в переменную экземпляра origin (рис. 8.7).

Рис. 8.7. Задание начала (origin) прямоугольника

Поскольку myPoint и переменная origin, хранящаяся в myRect, ссылаются на одну и ту же область в памяти (как и локальная переменная pt), при последующем изменении значения myPoint на (50,50) изменяется и значение начала прямоугольника.

Чтобы избежать этой проблемы, нужно модифицировать метод setOrigin: так, чтобы он выделял (alloc) свою собственную точку и присваивал началу прямоугольника (origin) эту точку. -(void) setOrigin: (XYPoint *) pt { origin = [[XYPoint alloc] init]; [origin setX: pt.x andY: pt.y]; }

Метод сначала выделяет память и инициализирует новый объект класса XYPoint. В выражении для сообщения [origin setX: pt.x andY: pt.y];

новому объекту класса XYPoint присваивается значение координат х,у аргумента, передаваемого методу.

Это изменение в методе setOrigin: означает, что теперь каждый экземпляр Rectangle владеет свои собственным экземпляром XYPoint. Теперь он не только осуществляет выделение памяти для XYPoint, но и освобождает эту память. Если класс содержит другие объекты, бывает нужно, чтобы он владел некоторыми или всеми объектами. Для прямоугольника класс Rectangle должен владеть объектом начала (origin) прямоугольника, поскольку это один из основных атрибутов.

Но была ли освобождена память, которая использовалась для origin? Освобождение памяти, занятой для прямоугольника (myRect), не освобождает память, которая была выделена для начала прямоугольника (origin). Чтобы освободить эту память, нужно вставить в main строку [[myRect origin] release];

В результате будет освобожден объект XYPoint, возвращаемый методом origin. Вы должны сделать это до того, как освободите память для самого объекта Rectangle, поскольку ни одна из переменных, содержащихся в этом объекте, недействительна после того, как освобождена память объекта. Необходима следующая последовательность строк кода. [[myRect origin] release]; //

Освобождение памяти для origin [myRect release]; // Освобождение памяти для прямоугольника

Вы вынуждены помнить, что нужно освобождать память непосредственно для origin, хотя не вы выделяли эту память; это сделал класс Rectangle. В следующем разделе, «Замещающие методы», вы узнаете, как сделать, чтобы Rectangle освобождал память.

После перекомпиляции и перезапуска программы 8.5 с модифицированным методом появляются сообщения об ошибках (рис. 8.8).

Рис. 8.8. Сообщения компилятора об ошибках

Проблема возникает из-за того, что мы использовали в модифицированном методе некоторые методы из класса XYPoint, и теперь компилятору требуется больше информации об этом классе, чем дает директива @class. Нужно вернуться назад и заменить эту директиву импортом: #import "XYPoint.h

Вывод программы 8.5В Origin at (100, 200) Origin at (100, 200)

Это уже лучше. Теперь изменение значения myPoint на (50, 50) внутри main не окажет никакого влияния на координаты начала прямоугольника, поскольку копия этой точки была создана внутри метода setOrigin: объекта Rectangle. Мы не синтезировали здесь методы origin, поскольку синтезированный метод-установщик setOrigin: будет действовать точно так же, как метод, написанный нами первоначально. По умолчанию синтезированный метод-установщик просто копирует указатель объекта, а не сам объект.

Вы можете синтезировать другой тип метода-установщик, который создает копию объекта, но для этого вам нужно научиться писать копирующий метод. Мы вернемся к этой теме в главе 17. 8.3. Замещающие методы

Выше уже говорилось, что мы не можем удалить или обойти методы при наследовании, но можем изменить определение наследуемого метода путем замещения. Возвращаясь к двум классам, ClassA и ClassB, предположим, что нужно написать собственный метод initVar для ClassB. Мы уже знаем, что ClassB будет наследовать метод initVar, определенный в классе ClassA, но можно ли создать новый метод с тем же именем для замены наследуемого метода? Да, можно, для этого нужно просто определить новый метод с тем же именем. Метод, определенный с таким же именем, как в родительском классе, заменяет, или замещает (override), унаследованное определение. Новый метод должен иметь такой же тип возвращаемого значения и принимать такое же число аргументов такого же типа, как метод, который вы замещаете.

В программе 8.6 показан простой пример, отражающий эту концепцию. // Замещающие методы #import <Foundation/Foundation.h> // Объявление и определение класса ClassA @interface ClassA: NSObject { int x; -(void) initVar; @end @implementation ClassA -(void) initVar { x = 100; } @end // Объявление и определение класса ClassB @interface ClassB: ClassA -(void) initVar; -(void) printVar; @end @implementation ClassB -(void) initVar // добавляемый метод { x = 200; -(void) printVar { NSLog (@"x = %i", x); @end int main (int argc, char *argv[]) { NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; ClassB *b = [[ClassB alloc] init]; [b initVar]; // использование замещающего метода в В [b printVar]; // раскрытие значения х; [b release]; [pool drain]; return 0; }

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

Сирота

Ланцов Михаил Алексеевич
1. Помещик
Фантастика:
альтернативная история
5.71
рейтинг книги
Сирота

Чужак из ниоткуда

Евтушенко Алексей Анатольевич
1. Чужак из ниоткуда
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Чужак из ниоткуда

Боярич Морозов

Шелег Дмитрий Витальевич
3. Наследник старого рода
Фантастика:
героическая фантастика
боевая фантастика
альтернативная история
7.12
рейтинг книги
Боярич Морозов

Андер Арес

Грехов Тимофей
1. Андер Арес
Фантастика:
рпг
аниме
фэнтези
фантастика: прочее
5.00
рейтинг книги
Андер Арес

Последний Герой. Том 5

Дамиров Рафаэль
5. Последний герой
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Последний Герой. Том 5

Запечатанный во тьме. Том 2

NikL
2. Хроники Арнея
Фантастика:
уся
эпическая фантастика
фэнтези
5.00
рейтинг книги
Запечатанный во тьме. Том 2

Спасите меня, Кацураги-сан! Том 3

Аржанов Алексей
3. Токийский лекарь
Фантастика:
городское фэнтези
попаданцы
дорама
фэнтези
5.00
рейтинг книги
Спасите меня, Кацураги-сан! Том 3

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

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

Лейб-хирург

Дроздов Анатолий Федорович
2. Зауряд-врач
Фантастика:
альтернативная история
7.34
рейтинг книги
Лейб-хирург

Двойник Короля

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

Надуй щеки! Том 2

Вишневский Сергей Викторович
2. Чеболь за партой
Фантастика:
попаданцы
дорама
фантастика: прочее
5.00
рейтинг книги
Надуй щеки! Том 2

Барон переписывает правила

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

Любимая учительница

Зайцева Мария
1. совершенная любовь
Любовные романы:
современные любовные романы
эро литература
8.73
рейтинг книги
Любимая учительница

Неучтенный элемент. Том 2

NikL
2. Антимаг. Вне системы
Фантастика:
городское фэнтези
фэнтези
5.00
рейтинг книги
Неучтенный элемент. Том 2