It's hard to explain, but basically what I am trying to do is call a completion handler in a block-based method from a delegate method.
这很难解释,但基本上我要做的是从委托方法调用基于块的方法中的完成处理程序。
I have the method where I call the upload function.
我有一个方法叫做上传函数。
[[UploadManager sharedManager] uploadFile:@"/Path/To/Image.png" success:^(NSDictionary *response) {
NSLog(@"Uploaded");
}];
Inside of the UpLoad manager, the method performs all the necessary actions to upload the file.
在上传管理器内部,该方法执行上传文件所需的所有操作。
There is a delegate method that I want to call the success block from.
有一个委托方法,我想从它调用success block。
- (void)fileDidUploadAndReceiveData:(NSData *)data {
NSDictionary *response = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&parseError];
// Call the completion method
success(response);
}
success is defined in the uploadFile method. How would I go about calling this completion handler?
成功定义在uploadFile方法中。如何调用这个完成处理器?
I wrote this late at night so if it doesn't make sense, let me know.
我写这篇文章写得很晚,如果没有道理,告诉我。
Thanks
谢谢
5 个解决方案
#1
11
Declare a property that is a copy of the block:
声明为该区块副本的属性:
@property(nonatomic, copy) void (^completionBlock)(NSDictionary *);
Assign it in uploadFile:
分配还是:
- (void)uploadFile:(NSString *)url success:(void (^)(NSDictionary *))completionBlock {
self.completionBlock = completionBlock;
// ...
Then call it whenever you want:
然后你需要的时候就叫它:
if (self.completionBlock) self.completionBlock(someDictionary);
self.completionBlock = nil; // see below
Remember that, if you don't need the block again (which you probably don't since the download is complete) that it's a good practice to nil out your copy of the block. This way, if the caller refers to the download manager within the block, you'll break the retain cycle for him (the block would retain the download manager which retains the block).
请记住,如果您不再需要这个块(由于下载完成,您可能不需要这个块),那么使用nil表示块拷贝的方法是很好的做法。这样,如果调用者在块中引用下载管理器,您将为他中断retain cycle(这个块将保留保存该块的下载管理器)。
#2
0
Create an instance variable in your UploadManager
class for the success block. Set this ivar in the uploadFile:success:
method. Then use this ivar to call the block in your fileDidUploadAndReceiveData:
method.
在UploadManager类中为成功块创建一个实例变量。在uploadFile中设置这个ivar:success:方法。然后使用这个ivar调用fileDidUploadAndReceiveData:方法中的块。
#3
0
in addition to my comment above this is how I normally handle block operations
除了上面的注释之外,这也是我通常处理块操作的方式
in your UploadManager.h file define a type
在你UploadManager。h文件定义类型
//// .h file
/ / / / . h文件
typedef void (^ActionNameBlock)(id responseObject);
- (void)setAction:(ActionNameBlock)actionBlock;
in your UploadManager.m file
在你UploadManager。m文件
//// .m file
/ / / / m文件
@property (nonatomic, copy) ActionNameBlock action;
- setAction:(ActionNameBlock)_action
{
self.action = _action;
}
// now in your block operation code
[[UploadManager sharedManager] uploadFile:@"/Path/To/Image.png" success:^(NSDictionary *response)
{
NSLog(@"Uploaded");
if (self.action) { self.action(response); }
}];
#4
0
The fileDidUploadAndReceiveData
is defined in the UploadManager
?
fileDidUploadAndReceiveData是在UploadManager中定义的吗?
If yes then you could just store a copy of the success block and call it exactly the way you wrote it.
如果是的话,你就可以存储一个成功块的拷贝,并按你写的方式调用它。
Inside your UploadManager header just add a copy block property:
在您的UploadManager头中,只需添加一个复制块属性:
typedef void (^OnUploadFileSuccesBlock)(NSDictionary *response);
@interface UploadManager : NSObject
@property (nonatomic, copy) OnUploadFileSuccesBlock uploadFileSucces;
Keep a copy of the success block in the uploadFile method :
在uploadFile方法中保存成功块的副本:
- (void) uploadFile:(NSString*)path success:(OnUploadFileSuccesBlock)block {
self.uploadFileSucces = block
...
}
And in your delegate method you can just call it :
在你的委托方法中你可以叫它:
- (void)fileDidUploadAndReceiveData:(NSData *)data {
NSDictionary *response = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&parseError];
// Call the completion method
self.uploadFileSucces(response);
}
#5
0
Add property @property (nonatomic, copy) void (^tempSuccess)(NSDictionary * response);
in UploadManager
添加@ property属性(原子、复制)空(^ tempSuccess)(NSDictionary *反应);在UploadManager
in uploadFile method assign
还是方法分配
self.tempSuccess = success;
and finally
最后
- (void)fileDidUploadAndReceiveData:(NSData *)data {
NSDictionary *response = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&parseError];
// Call the completion method
self.tempSuccess(response);
}
Hope it helps !
希望它可以帮助!
#1
11
Declare a property that is a copy of the block:
声明为该区块副本的属性:
@property(nonatomic, copy) void (^completionBlock)(NSDictionary *);
Assign it in uploadFile:
分配还是:
- (void)uploadFile:(NSString *)url success:(void (^)(NSDictionary *))completionBlock {
self.completionBlock = completionBlock;
// ...
Then call it whenever you want:
然后你需要的时候就叫它:
if (self.completionBlock) self.completionBlock(someDictionary);
self.completionBlock = nil; // see below
Remember that, if you don't need the block again (which you probably don't since the download is complete) that it's a good practice to nil out your copy of the block. This way, if the caller refers to the download manager within the block, you'll break the retain cycle for him (the block would retain the download manager which retains the block).
请记住,如果您不再需要这个块(由于下载完成,您可能不需要这个块),那么使用nil表示块拷贝的方法是很好的做法。这样,如果调用者在块中引用下载管理器,您将为他中断retain cycle(这个块将保留保存该块的下载管理器)。
#2
0
Create an instance variable in your UploadManager
class for the success block. Set this ivar in the uploadFile:success:
method. Then use this ivar to call the block in your fileDidUploadAndReceiveData:
method.
在UploadManager类中为成功块创建一个实例变量。在uploadFile中设置这个ivar:success:方法。然后使用这个ivar调用fileDidUploadAndReceiveData:方法中的块。
#3
0
in addition to my comment above this is how I normally handle block operations
除了上面的注释之外,这也是我通常处理块操作的方式
in your UploadManager.h file define a type
在你UploadManager。h文件定义类型
//// .h file
/ / / / . h文件
typedef void (^ActionNameBlock)(id responseObject);
- (void)setAction:(ActionNameBlock)actionBlock;
in your UploadManager.m file
在你UploadManager。m文件
//// .m file
/ / / / m文件
@property (nonatomic, copy) ActionNameBlock action;
- setAction:(ActionNameBlock)_action
{
self.action = _action;
}
// now in your block operation code
[[UploadManager sharedManager] uploadFile:@"/Path/To/Image.png" success:^(NSDictionary *response)
{
NSLog(@"Uploaded");
if (self.action) { self.action(response); }
}];
#4
0
The fileDidUploadAndReceiveData
is defined in the UploadManager
?
fileDidUploadAndReceiveData是在UploadManager中定义的吗?
If yes then you could just store a copy of the success block and call it exactly the way you wrote it.
如果是的话,你就可以存储一个成功块的拷贝,并按你写的方式调用它。
Inside your UploadManager header just add a copy block property:
在您的UploadManager头中,只需添加一个复制块属性:
typedef void (^OnUploadFileSuccesBlock)(NSDictionary *response);
@interface UploadManager : NSObject
@property (nonatomic, copy) OnUploadFileSuccesBlock uploadFileSucces;
Keep a copy of the success block in the uploadFile method :
在uploadFile方法中保存成功块的副本:
- (void) uploadFile:(NSString*)path success:(OnUploadFileSuccesBlock)block {
self.uploadFileSucces = block
...
}
And in your delegate method you can just call it :
在你的委托方法中你可以叫它:
- (void)fileDidUploadAndReceiveData:(NSData *)data {
NSDictionary *response = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&parseError];
// Call the completion method
self.uploadFileSucces(response);
}
#5
0
Add property @property (nonatomic, copy) void (^tempSuccess)(NSDictionary * response);
in UploadManager
添加@ property属性(原子、复制)空(^ tempSuccess)(NSDictionary *反应);在UploadManager
in uploadFile method assign
还是方法分配
self.tempSuccess = success;
and finally
最后
- (void)fileDidUploadAndReceiveData:(NSData *)data {
NSDictionary *response = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&parseError];
// Call the completion method
self.tempSuccess(response);
}
Hope it helps !
希望它可以帮助!