我正在开发一个模型类,提供从网络解析的数据。当然,我希望我的应用程序能够响应,因此网络应该在单独的线程/队列上完成。模型与背景网络的优选设计模式
这导致了问题:我该如何设计我的类的@interface?
的主要要求是:
- 应该从模型视图控制器:)传送数据;
- 它不应该阻止主(UI)线程;
- 它应该很容易理解,并由其他开发人员跟随。
从我从WWDC2012视频中学到的“在iOS上构建并发用户界面”Apple建议将并发代码移动到使用模型的类本身。
假设我们有Posts类(Posts.h/.m),它应该为ViewController提供NSArray *格式的最新帖子。
选项I - 并发类用户
类本身是不是并发,但用户有:
//Posts.h:
@interface Posts : NSObject
- (NSArray*)getPostsForUser:(NSString*)user;
@end
//ViewController.m
@implementation ViewController
- (void)someFunctionThatUpdatesUI
{
//<...>
NSOperationQueue *q = [[NSOperationQueue alloc] init];
[q addOperationWithBlock:^{
NSArray *currentPosts = [Posts shared] getPostsForUser:@"mike";
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
//UI should be updated only on main thread
[self updateUIWithPosts:currentPosts];
}];
}];
//<...>
}
这种方法的主要缺点是需要重复几乎每个ViewController中都有相同的代码。如果有几十个呢?
方案二 - 并发与完成处理模式
,我现在在我的应用程序中使用第二个选项是完成处理模式。如果进行一些长期的网络只后完成处理程序被调用,它不会阻塞主线程:
//Posts.h:
@interface Posts : NSObject
- (NSError*)getPostsForUser:(NSString*)user
withCompletionHandler:(void(^)(NSArray*))handler;
@end
@implementation Posts
- (NSError*)getPostsForUser:(NSString*)user
withCompletionHandler:(void(^)(NSArray*))handler
{
//<...>
dispatch_async(dipatch_get_global_queue(0, 0), ^{
//Do some may-be-long networking stuff here,
//parse, etc and put it into NSArray *result
dispatch_async(dipatch_get_main_queue(), ^{
handler(result);
});
});
//<...>
}
//ViewController.m
- (void)someFunctionThatUpdatesUI
{
//<...>
[Posts shared] getPostsForUser:@"mike"
withCompletionHandler:^(NSArray* posts){
//updateUI with posts
}];
}
从我的角度来看,这种方式是好的,但在@interface是相当复杂的,方法名称很长并且(从我的角度来看)混淆。
方案三 - 委托模式
,我看到的是委托模式的另一种选择。令我困扰的是,只有一个ViewController可能是委托,因此它导致必须将每个VC设置为委托 - viewWillAppear,这很容易忘记。
//Posts.h:
@protocol PostUpdate<NSObject>
- (void)updateUIWithPosts:(NSArray*)posts FromUser:(NSString*)user;
@end
@interface Posts
- (NSError*)updatePostsFromUser:(NSString*)user;
@property(nonatomic, weak) id<PostUpdate> delegate;
@end
//ViewController.m:
@implementation ViewController<PostUpdate>
- (void)viewWillAppear
{
//<...>
[Posts shared].delegate = self;
}
- (IBAction)getLatestsPostButtonPressed:(id)sender
{
[[Posts shared] updatePostsFromUser:@"mike"];
}
// protocol PostUpdate
- (void)updateUIWithPosts:(NSArray*)posts FromUser:(NSString*)user
{
//updating UI with posts
}
@end
所以这里的问题:
- 还有什么模式适合于提供从模型数据非阻塞方式控制器要求?
- 根据你的经验,实践或理论知识,你会推荐什么样的选择?
我不是母语,所以如果你是,请告诉我关于语法,语法或任何其他错误。 –