How do I pass a block, and what would it look like, in the method incrementCount:completion
to get the property self.count
returned after its increment in the CounterClass? I'm not sure if the way I defined the block parameter (void(^)(void))callback;
in the method is correct i.e. should it also have a return value?
ViewController
[NSTimer scheduledTimerWithTimeInterval:3.0
target:self.counterClass
selector:@selector(incrementCount:completion:)
userInfo:nil
repeats:YES];
CounterClass
-(void)incrementCount:(NSTimer *)timer completion:(void(^)(void))callback;
{
self.count += 1;
}
NSTimer
expects to call a method which takes zero or one parameters, if there is a parameter it should be the timer instance itself.
So, you can't have a method with 2 parameters where one is a block.
Instead, remove the second parameter and simply call another method or block in the method implementation. The block could be stored as an @property of the class.
You can used dispatch_after.
ViewController:
[self.counterClass incrementCountWithCompletion:^{
// Your block code
NSLog(@"block code");
}];
CounterClass:
-(void)incrementCountWithCompletion:(void(^)(void))block;
{
dispatch_time_t delay = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3.0 * NSEC_PER_SEC));
dispatch_queue_t queue = dispatch_get_main_queue(); // Choose whatever queue is approapriate to you
//Beware of retain cycles and use weak self pattern appropriately
dispatch_after(delay, queue, ^{
self.count += 1;
block();
[self incrementCountWithCompletion:block];
});
}
You can add your block to the userInfo
:
[NSTimer scheduledTimerWithTimeInterval:3.0 target:self.counterClass selector:@selector(incrementCount:) userInfo:@{@"completion" : [yourBlock copy]} repeats:YES];
CounterClass
- (void)incrementCount:(NSTimer *)timer {
self.count += 1;
void (^completion)(void) = timer.userInfo[@"completion"];
}
For more on storing a block in a dictionary: blocks in nsdictionary?