我有一个iPodLibraryGroup对象,而Artist和Album都继承了它。
当涉及到我的视图控制器时,虽然我发现我正在复制大量代码,例如我有一个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 :(得分:3)
重构您的代码,以便您拥有一个可在iPodLibraryGroup对象上运行的通用ListViewController,并拥有ArtistListViewController& AlbumListViewController都继承自它。
将所有常用部分推送到通用ListViewController,并让您的Artist / Album控制器仅实现/覆盖需要采取不同行为的方法。
答案 1 :(得分: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方法之前将我的“source”引用转换为(iPodLibraryGroup *)来解决它,例如:
[(iPodLibraryGroup *)source addObserver:self forKeyPath:@"pendingResponseForDetailedInfo" options:0 context:nil];