Могу ли я избежать явного приведения объектов с общим подклассом? - PullRequest
3 голосов
/ 05 апреля 2010

У меня есть объект iPodLibraryGroup, и Artist и Album оба наследуются от него.

Когда дело доходит до моих контроллеров представления, хотя я нахожу, что я дублирую много кода, например, у меня есть ArtistListViewController и и AlbumListViewController, хотя они оба делают в основном то же самое.

Причина, по которой я в итоге продублировал код, заключается в том, что каждый из этих контроллеров представления ссылается либо на объект Artist, либо на объект al al Album, и я не уверен, как его настроить, чтобы один контроллер представления мог обрабатывать оба - эти контроллеры представления в основном обращаются к методам, которые являются общими для объектов из iPodLibraryGroup.

В качестве примера, чтобы, надеюсь, сделать это более понятным, рассмотрим этот код в AlbumListViewController:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

    Album *album = nil; 
    album = [self albumForRowAtIndexPath:indexPath inTableView:tableView];

    …

    if (!album.thumbnail)
    {
        [self startThumbnailDownload:album forIndexPath:indexPath inTableView:tableView];
        cell.imageView.image = [UIImage imageNamed:@"Placeholder.png"];                
    }
    else
    {
       cell.imageView.image = album.thumbnail;
    }


    return cell;
}

Это по существу полностью повторяется (наряду с чертовски многократно повторяющимся кодом) в ArtistListViewController просто для того, чтобы я мог типизировать локальную переменную как Исполнитель вместо Альбома.

Есть ли способ не явно указывать здесь Artist или Album, чтобы один и тот же код мог работать для любого объекта, являющегося дочерним для iPodLibraryGroup?

Ответы [ 2 ]

3 голосов
/ 05 апреля 2010

Выполните рефакторинг вашего кода, чтобы у вас был общий ListViewController, который работает с объектами iPodLibraryGroup, и оба объекта ArtistListViewController и AlbumListViewController наследуются от него.

Переместите все общие части до универсального ListViewController, и ваши контроллеры Artist / Album реализуют / переопределяют только те методы, которые должны вести себя по-разному.

0 голосов
/ 05 апреля 2010

На основе предложения, полученного в твиттере Я создал протокол на iPodLibraryGroup следующим образом:

@protocol iPodLibraryGroup <NSObject>
@required

@property (nonatomic, retain) NSString *name;
@property (nonatomic, retain, readonly) NSString *sort_name;

…

- (void)downloadImageFromURL:(NSURL *)image_url;
- (void)cancelImageDownload;
- (void)downloadImageCannotStart;

@end


@interface iPodLibraryGroup : NSObject <iPodLibraryGroup> {

…

}

Затем в контроллерах моего представления вместо объявления указателей на объявленных исполнителей или альбомов я использую синтаксис:

id <iPodLibraryGroup> source;

Единственная проблема, с которой я столкнулся, была при вызове методов NSObject, я получал бы предупреждение компилятора:

Эта проблема обсуждается в Как типизировать идентификатор динамически в конкретный класс во время выполнения? , и я решил ее, приведя ссылку на «источник» как (iPodLibraryGroup *) перед вызовом методов NSObject, пример:

[(iPodLibraryGroup *)source addObserver:self forKeyPath:@"pendingResponseForDetailedInfo" options:0 context:nil];
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...