3

I use cocos2D for iphone.

I have 3 scenes: scene A,scene B, and scene C

  1. in scene C, click to open scene A, but scene A is not opened yet;
  2. open scene B first, scene B has many buttons
  3. users click a button on scene B, then scene B dismisses and returns a value v to scene C;
  4. according to value v, scene C decides to open or not open scene A;

All I need is a callback function, I use delegate to accomplish this successfully.

I have a protocol:

@protocol SceneBDelegate <NSObject>
@required
- (void)dismissWithValue:(BOOL)value;
@end

In scene B, when a button is clicked:

-(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 accomplish this with block?

I have readed about Jens Ayton's post is this question, how-to-perform-callbacks-in-objective-c

He explains how to use block, but I can't figure out how to connect users' action with block.

I konw UIViewController has a I found when using UIViewController has a function:

(void)dismissViewControllerAnimated: (BOOL)flag completion: (void (^)(void))completion NS_AVAILABLE_IOS(5_0);

it supports block.

But I use cocos2D, I didn't find a similar funciton.

Can anyone give me some advices? Thanks a lot!

Community
  • 1
  • 1
abentotoro
  • 225
  • 2
  • 13

3 Answers3

1

Your scene B probably has an

@property (nonatomic, weak) id<SceneBDelegate> delegate;

instead you can store a block in a property:

@property (copy)void (^dismissWithValueBlock)(BOOL); // dismissWithValueBlock is the name of the variable.

Then in your scene B, when the button is pressed you do:

-(void) clickBtn{

    if(self.dismissWithBlock){
        self.dismissWithBlock(YES)
    }

    [self removeFromParent];
}

To create the block in your other class you should 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'
}
Nils Ziehn
  • 4,118
  • 6
  • 26
  • 40
0

Yo can do that as bellow

//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)
{

}];
Rajesh
  • 948
  • 7
  • 13
0

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 a different 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....
}];
}

I hope this helps.

orenk86
  • 720
  • 9
  • 24