Objective-C и компонентное программирование
Я пытаюсь реализовать концепцию компонентного программирования при написании своей игры для iOS.
В книге Клеменса Шиперского "Компонентное программное обеспечение: помимо объектно-ориентированного программирования" он упоминает тактику:
(не в кавычках) Начните с класса Duck, который добавляет компонент Quack. Класс Quack реализует интерфейс для любого вызывающего его объекта, интерфейс определяет метод, который использует Quacks quack()
С этой настройкой Duck не имеет никаких сведений или сведений о Quack, за исключением случаев, когда он создается, и после этого никогда не используется в Duck. Другие объекты могут вызывать duckObject.quack() и достигать Quack, зная только об объекте Duck.
До сих пор я пытался реализовать это без успеха. Желательно, чтобы Duck не нуждался в коде больше, чем в экземпляре, остальные должны быть помещены в класс Quack. Можно ли это сделать в Objective-C (для iOS?) Или мне лучше оставить COP для других языков?
2 ответа
Я не думаю, что в ObjC есть точное сравнение, но похоже, что вы хотите изучить пересылку сообщений. Если объекту отправляется сообщение, на которое он не отвечает, перед сигналом ошибки, среда выполнения отправляет объект forwardInvocation:
, с NSInvocation
аргумент, который инкапсулирует сообщение и аргументы.
В forwardInvocation:
объект может передавать вызов другому объекту, который обрабатывает это сообщение. Это позволяет Duck
экземпляр для ответа на сообщение quack
, даже если quack
не реализуется Duck
удерживая ссылку на экземпляр Quack
, который реализует это:
- (void)forwardInvocation:(NSInvocation *)anInvocation
{
if( [myQuack respondsToSelector:[anInvocation selector]] ){
[anInvocation invokeWithTarget:someOtherObject];
}
else{
[super forwardInvocation:anInvocation];
}
}
Не совсем уверен, что ваш вопрос. Похоже, вы хотите слабую ссылку на класс. Первый класс утки
//Duck.h
#import "Quack.h"
@interface Duck : NSObject {
Quack *quacker;
}
@property (nonatomic, retain) Quack *quacker;
@end
//Duck.m
@implementation Duck
@synthesize quarker;
-(id) init {
self = [super init];
if(self) {
}
return self;
}
-(Quack *)quacker {
if(quacker == nil) {
[self setQuacker:[[[Quack alloc] init] autorelease]];
}
return quacker;
}
@end
Затем реализуйте класс Quack.
//Quack.h
@interface Quack : NSObject {
}
-(void)quack;
@end
//Quack.m
@implementation Quack
-(id) init {
self = [super init];
if(self) {
}
return self;
}
-(void)quack {
NSLog(@"quack");
}
@end
Теперь в каком классе вы хотите:
//RandomClass.m
[[[self duck] quacker] quack];