如何从objective-c中的另一个方法执行完成块?

问题描述:

是否无法获得完成块成功,然后从另一个方法接收数据?如何从objective-c中的另一个方法执行完成块?

@property myCompletion; 

// I have first call listeners, i can't add this in to "createOrderWithsuccess" 

-(void)listeners { 
    [[SocketIOManager sharedInstance].socket on:@"someAction" callback:^(NSArray* data, SocketAckEmitter* ack) { 
     // data received 
     myCompletion(data); 

    }]; 

} 

// this will be called <del>first</del> later 
- (void)createOrderWithsuccess:^(NSArray *data) { 
    // but it has to wait then data will be received 
    myCompletion = success; 
} 

这是一个有点难以明白你在找什么,但这个可能吧。这是我如何处理完成回调,在我的应用程序:

@import Foundation; 

typedef void (^CompletionBlock)(NSArray *data); 

@interface TheClass() 

@property (nonatomic, copy) CompletionBlock *myCompletion; 

@end 

@implementation TheClass() 

// .... 


- (void) createOrderWithsuccess:(CompletionBlock)success { 
    _myCompletion = success; 
} 

-(void)listeners { 
    [[SocketIOManager sharedInstance].socket on:@"someAction" callback:^(NSArray* data, SocketAckEmitter* ack) { 
     // data received 
     _myCompletion(data); 

    }]; 
} 

// Alternatively, breaking possible retain cycles 
-(void)listeners { 
    __weak TheClass *weakSelf = self; 
    [[SocketIOManager sharedInstance].socket on:@"someAction" callback:^(NSArray* data, SocketAckEmitter* ack) { 
     // data received 
     if(weakSelf.myCompletion) weakSelf.myCompletion(data); 
    }]; 
} 

typedef应在.h文件,使这两个类和一个叫createOrderWithsuccess:知道。

+0

不要开玩笑。我在这行上有'ERROR ** EXC_BAD_ACCESS(code = 1,address = 0xc)**'_myCompletion(data);' –

+0

你是不是先调用'createOrderWithSuccess:'?你可以在if语句中调用'_myCompletion(data)':if(_myCompletion)_myCompletion(data)'。 – Joakim

+0

谢谢,它的工作:)我需要添加'if(_myCompletion)_myCompletion(data)_myCompletion = nil;'?根据hanh answer.With'_myCompletion = nil'它只会工作一次。我无法设置_myCompletion = nil,因为监听器会多次调用。 –

如果我正确理解你的意图,这个想法很好。呼叫者可以使用createOrderWithsuccess:方法作为完成块的setter。随后,呼叫者呼叫listeners,了解到他们早先设置的块将在成功时被调用。

这很好,但考虑几件事情:(1)复制块...

@property (nonatomic, copy) void (^myCompletion)(NSArray *); 

(1.5)的块将被更好地命名为“successHandler”或类似的东西,和特性都可被公开,所以你可以删除createOrderWithsuccess:二传手。

(2)既然你不知道,如果呼叫者已调用之前设置块,检查零(这是否则崩溃)

if (self.myCompletion) self.myCompletion(data); 

(3)零块,你是通过后用它。如果块引用该对象,则删除它将打破保留周期。

if (self.myCompletion) self.myCompletion(data); 
self.myCompletion = nil; 
+0

“createOrderWithsuccess”的外观应该如何? –

+0

正如我所建议的,如果该块是一个属性,您可以将其设为公共属性,并且呼叫者可以直接分配。如果你真的想把这个任务放在createWithSuccess中,那么就是一行分配,就像你有这个任务一样好。 – danh