How to pass a block as selector with param to performSelector:withObject:?

做~自己de王妃 提交于 2019-12-11 18:43:50

问题


Is it possible to create a block variable as selector accepting parameters, and to pass it to performSelector:withObject:? Currently, writing some tests and want to write a self contained method with all related checking. Need to pass a block, receive the param in it and do some checking in that block. I'm looking for something like:

...
SEL blockAsSelector = ^{(NSString *param){NSLog(@"Passed param = %@", param);}}

[self performSelector:blockAsSelector withObject:stringThatWillBeUsedAsParamInBlock];
...

回答1:


Is it possible to create a block variable as selector accepting parameters, and to pass it to performSelector:withObject:?

No. Blocks and selectors are not the same thing.

In your example, it doesn't make sense. -performSelector:withObject: runs synchronously on the same thread. You might as well just execute the block i.e.

void (^myBlock)(NSString*) = ^(NSString *param){NSLog(@"Passed param = %@", param);};

myBlock(@"foo");

If you want to do the work in the block concurrently, you would use GCD or am NSBlockOperation.




回答2:


If you don't need a delay to perform the operation you can:

[[NSOperationQueue mainQueue] addOperationWithBlock:^(void)block]



回答3:


I generally agree with other answers that you should try to find another way to do this, as selectors and blocks are really not that interchangeable. But if you absolutely had to do it this way, I think something like this would be your best bet:

// BlockWrapper.h

@interface BlockWrapper : NSObject

@property(nonatomic, retain) void (^block)(NSString*);
@property(nonatomic, copy) NSString* string;

@end



// Your other code file

- (void)evaluateBlockWrapper:(BlockWrapper)wrapper {
    wrapper.block(wrapper.string);
}

...
BlockWrapper* wrapper = [[BlockWrapper alloc] init];
wrapper.block = ^(NSString* param) { NSLog(@"Passed param = %@", param); }
wrapper.string = stringThatWillBeUsedAsParamInBlock;

[self performSelector:@selector(evaluateBlockWrapper:) withObject:wrapper];
...

Although this makes me wonder why you want to have the block take a string parameter, instead of just referencing the string inside the block:

// Your other code file

- (void)evaluateBlock:(void (^)(void))block {
    block();
}

...
[self performSelector:@selector(evaluateBlock:)
    withObject:^{
        NSLog(@"Passed param = %@", stringThatWillBeUsedAsParamInBlock);
    }];
...

I'm not too sure about all the memory management here, so someone else will have to double check me on that.



来源:https://stackoverflow.com/questions/10246403/how-to-pass-a-block-as-selector-with-param-to-performselectorwithobject

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!