Протокол Objective C как равный интерфейсу Java? - PullRequest
4 голосов
/ 04 января 2010

Вопрос заключается не только в заголовке, но и в том, «как мне этого добиться, не пытаясь втиснуть дизайн Java / Flash в программу Objective C (iPhone)».

У меня есть 6 представлений, которые расширяют UIView, все эти представления имеют различное поведение, но используют определенные методы, такие как -(void) update и -(void) changeState:(NSInteger)state.

viewController, задачей которого является обновление, создание и отображение этих представлений, имеет блок переключателей для этого. Так что switch (4) {...} создает экземпляр UIView4, но, поскольку мне нужна ссылка на текущий экземпляр (для выполнения update и changeState:), у меня есть свойство UIView в ViewController, называемое self.currentView. Поскольку созданный экземпляр UIView4 расширяет UIView, я могу легко перейти на [self.currentView addSubview:UIView4instance] и затем выпустить экземпляр UIView4.

Теперь, как я вызову метод [UIView4instance update] в представлении? или [UIView5instance changeState] и т. д. и т. д. Поскольку я добавил его в self.currentView типа UIView, у него больше нет оснований полагать, что у него есть метод update или changeState:, то есть я не могу перебирать представления и отправлять им эти сообщения.

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

Если бы я делал что-то подобное подходу Composite Pattern, скажем, в Java. Я бы написал интерфейс, который бы реализовывал все виды (UIView1, UIview2 .... UIViewN). Или, может быть, абстрактный класс, от которого все представления унаследовали методы changeState: и update.

Таким образом, я мог бы self.currentView просто знать, что я добавляю объекты в ваше представление, и все они соответствуют этим методам.

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

Надеюсь, кто-то может указать мне правильное направление в отношении этих вопросов. Спасибо:)

Ответы [ 2 ]

8 голосов
/ 04 января 2010

Да, это равно. Вы можете объявить протокол

@protocol MyViewProtocol
-(void)update;
-(void)changeState:(NSInteger)state;
@end

и объявите ваши подклассы как

@interface MyUIView3 : UIView<MyViewProtocol> {
....
}
....
@end

Тогда декларация

UIView<MyViewProtocol>* view=[[MyUIView3 alloc] init];

означает, что view является экземпляром (подкласса) UIView, который также соответствует MyViewProtocol. Думаю, именно так и работает на Java. См. яблочный документ по протоколам .

4 голосов
/ 04 января 2010

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

Вы получите предупреждение для этого, но оно будет работать.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...