我已经为我的tableview实现了一个refreshcontrol,它运行正常。但我想实现调用另一个类来执行该类中的进程。我希望我的refreshcontrol应该等到该类的执行。
例如:我在Player类中有一些数据库更改。现在,当数据库更改正在进行时,refreshcontrol将结束刷新。
-(void)pullToRefresh{
UpdOther *updO = [[UpdOther alloc] initWithProfile:@"Player"];
[updO release];
[refreshControl endRefreshing];
}
答案 0 :(得分:1)
不是让pullToRefresh
方法等待更新,如果你只是在更新过程中使用了完成块会更好,所以pullToRefresh
可以告诉更新过程当更新已完成。
例如,不是让initWithProfile
执行更新过程,而是可以使用某种方法,比如performUpdateWithCompletion
这样做,但是给它一个完成块:
- (void)performUpdateWithCompletion:(void (^)(void))completionBlock
{
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
// do synchronous update here
// when done, perform the `completionBlock`
if (completionBlock) {
dispatch_async(dispatch_get_main_queue(), ^{
completionBlock();
});
}
});
}
然后您的pullToRefresh
可以指定更新过程在完成时要执行的操作,例如:
- (void)pullToRefresh{
UpdOther *updO = [[UpdOther alloc] initWithProfile:@"Player"];
__weak typeof(self) weakSelf = self;
[updO performUpdateWithCompletion:^{
typeof(self) strongSelf = weakSelf;
[strongSelf.refreshControl endRefreshing];
}];
[updO release];
}
还有其他方法(委托模式,通知模式),但我更喜欢基于块的解决方案的内联即时性。
顺便说一下,如果UpdOther
使用NSURLConnectionDataDelegate
方法,您显然需要从其他方法(例如completionBlock
)调用connectionDidFinishLoading
。因此,在这种情况下,您可以在UpdOther
中定义块属性,如下所示:
@property (nonatomic, copy) void (^updateCompletionBlock)(void);
或者,您可以为此块定义typedef
:
typedef void (^UpdateCompletionBlock)(void);
然后在你的财产声明中使用它:
@property (nonatomic, copy) UpdateCompletionBlock updateCompletionBlock;
无论如何,在这种情况下,您的performUpdateWithCompletion
会在该属性中保存该块的副本:
- (void)performUpdateWithCompletion:(void (^)(void))completionBlock
{
self.updateCompletionBlock = completionBlock;
// now initiate time consuming asynchronous update here
}
然后,无论您完成下载,都可以在那里调用已保存的完成块:
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
// do whatever extra steps you want when completing the update
// now call the completion block
if (self.updateCompletionBlock) {
dispatch_async(dispatch_get_main_queue(), ^{
self.updateCompletionBlock();
});
}
}