2010-03-27 4 views
1

У меня следующие фрагменты кода кода:iPhone: Общий протокол/делегатский код

@protocol FooDelegate;

@interface Foo: UIViewController { id delegate; } ...

@protocol FooDelegate ... // Метод 1 ... // Метод 2 ... @end

Кроме того, следующий код, который реализует FooDelegate:

@interface Bar1: UIViewController {...}

@interface bAR2: UITableViewController {...}

Оказывается, реализация FooDelegate одинакова для классов Bar1 и Bar2. В настоящее время я просто копирую код реализации FooDelegate с Bar1 на Bar2.

Как структурировать/реализовать таким образом, чтобы Bar1 и Bar2 совместно использовали один и тот же код в одной базе кода (а не в настоящее время с 2 копиями), так как они одинаковы?

Заранее за вашу помощь.

+0

Вы решили свою проблему?Я столкнулся с одним и тем же, и я не доволен каким-либо ответом, который я получил до сих пор :( – amok

ответ

0

Сделать новый объект, MyFooDelegate:

@interface MyFooDelegate : NSObject <FooDelegate> 

Тогда Bar1 и BAR2 каждый может создать экземпляр этого (или совместно использовать один экземпляр). В этих классах можно устранить методы делегата и добавить строки, подобно:

MyFooDelegate *myDooDelegateInstance = ...; 

foo.delegate = myFooDelegateInstance; 

Вы также можете создать экземпляр MyFooDelegate в файле NIB и подключения делегата точек контроллера представления к нему, если это необходимо.

Таким образом, у вас не будет дублированного кода в исходных файлах или в ваших исполняемых файлах.

+0

Я не думаю, что это действительно решает проблему. Оба Bar1 и Bar2 все равно должны добавлять код во все те же места чтобы подключиться к их экземпляру MyFooDelegate.Реальное решение было бы формой mixins, которую Cocoa на самом деле не имеет в этом случае. –

+1

Если проблема связана с тем же кодом в двух исходных файлах, это решительно решает проблему. – benzado

+1

Нет, он обменивает одну проблему на другую, потому что теперь у вас есть другой тип исходного кода, который является одним и тем же в двух исходных файлах. –

1

Вариант А: Реализация метода в категории

Любые свойства, используемые должны быть объявлены в UIViewController.

UITableViewController является подклассом UIViewController.

//UIViewController+MyAdditions.h 
@interface UIViewController (MyAdditions) 
- (void)myCommonMethod; 
@end 

//UIViewController+MyAdditions.m 

@implementation UIViewController (MyAddtions) 
- (void)myCommonMethod { 
// insert code here 
} 

Новый метод, добавленный к UIViewController будет наследоваться Bar1 и Bar2

Вариант B: Создание MyViewControllerHelper класса

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

@interface MyViewControllerHelper : NSObject 
- (void)myCommonMethod; 
@end 

@implementation MyViewControllerHelper 
- (void)myCommonMethod { 
    // common code here 
} 

@interface Bar1 : UIViewController { 
MyViewControllerHelper *helper; 
} 
@property MyViewControllerHelper *helper; 
@end 

@implementation Bar1 
@synthesize helper; 
- (void)someMethod { 
    [helper myCommonMethod]; 
} 
@end 

@interface Bar2 : UITableViewController { 
MyViewControllerHelper *helper; 
} 
@property MyViewControllerHelper; 
@end 

@implementation Bar2 
@synthesize helper; 
- (void)someOtherMethod { 
    [helper myCommonMethod]; 
} 
@end 
+0

Вариант A имеет некоторый ненужный риск, так как вы добавите методы делегата в класс UIViewController. Если протокол делегата является полностью настраиваемым, он, вероятно, безопасен, но если это системный протокол (например, UIActionSheetDelegate), вы теоретически можете разбить несвязанные вещи (например, системный диспетчер представления фотографий). – benzado

+0

Это всегда о выборе. Вариант A полностью исключает делегирование, которое, как я думал, может вызвать проблемы, поскольку UIViewController не реализует протокол делегатов, но UITableViewController делает это. Примеры Foo и Bar не обеспечивают достаточного контекста, чтобы определить, являются ли они полезными утилитами, которые * пропускают * из API (думаю, base64 кодировка строк). Любые риски должны быть сопоставлены с нарушением принципа * dry * и сложностью управления категорией или связью между контроллером и новыми вспомогательными объектами. – falconcreek

Смежные вопросы