IOS: how to execute this delegate code using a block
I am using cocos2D for iphone.
I have 3 scenes: scene A, scene B and scene C
- in scene C, press to open scene A, but scene A is not open yet;
- open scene B first, scene B has many buttons
- users press a button on scene B, then scene B discards and returns v to scene C;
- according to the value of v, scene C decides to open or not open scene A;
All I need is a callback function, I use a delegate to execute successfully.
I have a protocol:
@protocol SceneBDelegate <NSObject>
@required
- (void)dismissWithValue:(BOOL)value;
@end
In scene B, when the button is pressed:
-(void) clickBtn{
if([self.delegate respondsToSelector:@selector(dismissWithValue:)]){
[self.delegate dismissWithValue: YES];
}
[self removeFromParent];
}
In scene C,
-(void) dismissWithValue:(BOOL)value{
if(value){
// do something;
}
}
These codes work well, but I want to know how to do it with a block?
I read about Jens Ayton's post - this is a question, how-to-perform-callbacks-in-objective-c
He explains how to use a block, but I can't figure out how to link user actions to a block.
I konw UIViewController has I found that when using UIViewController there is a function:
(void)dismissViewControllerAnimated: (BOOL)flag completion: (void (^)(void))completion NS_AVAILABLE_IOS(5_0);
it maintains the block.
But I am using cocos2D, I have not found this functionality.
Can anyone give me some advice? Many thanks!
source to share
Your scene B has
@property (nonatomic, weak) id<SceneBDelegate> delegate;
instead, you can store the block in a property:
@property (copy) void (^ rejectWithValueBlock) (BOOL); // rejectWithValueBlock is the name of the variable.
Then, in your scene B, when the button is clicked, you do:
-(void) clickBtn{
if(self.dismissWithBlock){
self.dismissWithBlock(YES)
}
[self removeFromParent];
}
To create a block in another class, you must do this:
__weak typeof (self) weakSelf = self;
sceneB.dismissWithBlock = ^(BOOL value)
{
typeof (self) strongSelf = self;
// .... now your code you want to execute when this block is called..
// make sure not to call self.XXX anywhere in here. You should use the strongSelf.XXX insteadd! This is for memory management purposes. You can read up on it by googling 'strongSelf in blocks ios'
}
source to share
Yo can do it like below
//Define Block As in SceneBDelegate.h
typedef void (^onResultBlock)(NSDictionary *DictData, NSError *error);
- (void) onDismissWithValue:(onResultBlock) callbackBlock;
//Implementaion of Block As in SceneBDelegate.m
- (void) onDismissWithValue:(onResultBlock) callbackBlock
{
NSMutableDictionary *aMutDict = [[NSMutableDictionary alloc] init];
[aMutDict setValue:@"Value" forKey:@"Some Data"];
objCallback(aMutDict, nil);
}
//Call block from scene bellow
SceneBDelegate *aObjVC = [self.storyboard instantiateViewControllerWithIdentifier:@"SceneBDelegate"];
[aObjVC onDismissWithValue:^(NSDictionary *DictData, NSError *error)
{
}];
source to share
Try using this code:
@interface YourClass : NSObject {
void (^_block)(BOOL *result);
}
-(void) yourMethod:(NSString *)param1 withAnotherParam:(NSDictionary *)param2 withBlock:(void(^)(BOOL *result))block;
@implementation YourClass
-(void) yourMethod:(NSString *)param1 withAnotherParam:(NSDictionary *)param2 withBlock:(void(^)(BOOL *result))block
{
block = [block copy];
//do some stuff
block(YES);
}
And then when you call yourMethod
from another class, you can do:
@implementation OtherClass
-(void) otherMethod
{
//do other stuff
[yourClassInstance yourMethod:@"hello" withAnotherParam:@{@"hello": @"hello"} withBlock:(void(^)(BOOL *result)){
//do stuff in the block....
}];
}
Hope this helps.
source to share