Reputation: 837
I have a implemented a refreshcontrol for my tableview and it works fine. But I wanna achieve to invoke another class execute the process within that class. I want my refreshcontrol should wait until the execution of that class.
Eg: I have some database changes in the Player class. Now the refreshcontrol ends the refresh while the database changes are in progress.
-(void)pullToRefresh{
UpdOther *updO = [[UpdOther alloc] initWithProfile:@"Player"];
[updO release];
[refreshControl endRefreshing];
}
Upvotes: 1
Views: 736
Reputation: 437622
Rather than having the pullToRefresh
method wait for the update, it would be better if you simply used a completion block in your update process, so pullToRefresh
could tell the update process what to do when the update was done.
For example, rather than having the initWithProfile
perform the update process, you could have some method, say performUpdateWithCompletion
do it, but give it a completion block:
- (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();
});
}
});
}
Then your pullToRefresh
can specify what it wants the update process to do upon completion, for example:
- (void)pullToRefresh{
UpdOther *updO = [[UpdOther alloc] initWithProfile:@"Player"];
__weak typeof(self) weakSelf = self;
[updO performUpdateWithCompletion:^{
typeof(self) strongSelf = weakSelf;
[strongSelf.refreshControl endRefreshing];
}];
[updO release];
}
There are other approaches, too, (delegate pattern, notification pattern), but I prefer the in-line immediacy of the block-based solution.
By the way, if UpdOther
is using the NSURLConnectionDataDelegate
methods, you obviously need to call the completionBlock
from some other method (e.g., connectionDidFinishLoading
). So, in that case, you'd define a block property in UpdOther
as so:
@property (nonatomic, copy) void (^updateCompletionBlock)(void);
Or, you can define a typedef
for this block:
typedef void (^UpdateCompletionBlock)(void);
and then use that in your property declaration:
@property (nonatomic, copy) UpdateCompletionBlock updateCompletionBlock;
Anyway, in that case, your performUpdateWithCompletion
would save a copy of the block in that property:
- (void)performUpdateWithCompletion:(void (^)(void))completionBlock
{
self.updateCompletionBlock = completionBlock;
// now initiate time consuming asynchronous update here
}
And then, however you complete your download, you can call the saved completion block there:
- (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();
});
}
}
Upvotes: 1