2010-04-05 30 views
3

我有一個iPodLibraryGroup對象,藝術家和專輯都從它繼承。我可以避免顯式轉換具有公共子類的對象嗎?

當談到我的視圖控制器,雖然我發現我重複了很多代碼,例如我有一個ArtistListViewController和和AlbumListViewController,即使他們都做基本相同的事情。

我最終重複代碼的原因是因爲這些視圖控制器都引用Artist對象或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(有很多重複的代碼的地獄一起)只是讓我可以將局部變量作爲藝術家而不是專輯進行類型化。

有沒有一種方法可以不明確地在這裏設置藝術家或專輯,以便相同的代碼可以適用於任何iPodLibraryGroup的子對象?

回答

0

基於一個suggestion received on twitter我創建上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方法時,我會得到一個編譯器警告:

討論此問題在How to typecast an id to a concrete class dynamically at runtime?和我調用NSObject的方法解決之前,它鑄造了我的「源」引用作爲(iPodLibraryGroup *),例如:

[(iPodLibraryGroup *)source addObserver:self forKeyPath:@"pendingResponseForDetailedInfo" options:0 context:nil]; 
3

重構您的代碼,以便您擁有一個在iPodLibraryGroup對象上運行的通用ListViewController,並且ArtistListViewController & AlbumListViewController都從它繼承。

將所有公共部分推送到通用ListViewController,並讓您的Artist/Album控制器僅實現/覆蓋需要不同行爲的方法。

+0

這會工作得我想像,但該協議的解決方案標誌着我的答案是更快的實施。 – prendio2 2010-04-07 16:11:20

相關問題