I have an ill-understanding of block-based callbacks. There seems to be two approaches that I'm aware of and I don't know when I should be using one over the other so could someone please explain to me the differences between the two, correct me and give me some tips if I need any.
Some code I found off stackoverflow as well as a library from elsewhere so thanks to those who wrote this code.
typedef void (^MyClickedIndexBlock)(NSInteger index);
@interface YourInterface : YourSuperClass
@property (nonatomic, strong) MyClickedIndexBlock clickedIndexBlock
.m
//where you have to call the block
if (self.clickedIndexBlock != nil) {self.clickedIndexBlock(buttonIndex)};
// where you want to receive the callback
alert.clickedIndexBlock = ^(NSInteger index){NSLog(@"%d", index);};
my understanding with the above is that:
MyClickedIndexBlock is typedef to a NSInteger. Property created with the name "clickedIndexBlock" which is of type MyClickedIndexBlock (meaning that clickedIndexBlock can be a number).
Blocks can also be used as methods which is why I can call self.clickedIndexBlock(buttonIndex);
BUT something tells me that this approach as a @property only really supports one parameter eg. NSInteger.
WHEREAS the following approach allows for more than one parameter.
bluetoothMe.h
typedef void (^hardwareStatusBlock)(CBPeripheral *peripheral, BLUETOOTH_STATUS status, NSError *error);
- (void)hardwareResponse:(hardwareStatusBlock)block;
bluetoothMe.m
- (void)hardwareResponse:(hardwareStatusBlock)block {
privateBlock = [block copy];
}
- (void)centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral {
NSLog(@"Did connect to peripheral: %@", peripheral);
privateBlock(peripheral, BLUETOOTH_STATUS_CONNECTED, nil);
NSLog(@"Connected");
[peripheral setDelegate:self];
[peripheral discoverServices:nil];
}
My understanding that creating a property which is strong and doing a [block copy] will retain the block around until the app terminates. So [block copy] and strong both retain. [block copy] is applied to the block to retain otherwise the block would have vanished when the method goes out of scope.
ViewController.m
[instance hardwareResponse:^(CBPeripheral *peripheral, BLUETOOTH_STATUS status, NSError *error) {
if (status == BLUETOOTH_STATUS_CONNECTED)
{
NSLog(@"connected!");
}
else if (status == BLUETOOTH_STATUS_FAIL_TO_CONNECT)
{
NSLog(@"fail to connect!");
}
else
{
NSLog(@"disconnected!");
}
NSLog(@"CBUUID: %@, ERROR: %@", (NSString *)peripheral.UUID, error.localizedDescription);
}];
So lets see what my questions were:
1) When would I choose the first approach over the second approach and vice versa?
2) First example, the block was a typedef to a property. Second example, the block was declared a method. Why couldn't the first example be declared a method and why couldn'tt the second example be typedef to a property?
3) Would I need to create a typedef for every type of delegate method that I want a block-based callback for?
4) At of date, ive only seen one delegate method supported. Could you show me an example on how one would implement each approach if I was to create block-based callbacks on multiple delegate methods which are not similar.
Appreciate your feedback. This is hard at times. Need as much help as I can get. Thanks,
Ben