不,那不是问题,您可以在另一个块中访问该块。我认为问题是您已经在 mainQueue ([NSOperationQueue mainQueue]) 上,您再次尝试在 mainQueue 上 getMainQueue。因为 sendAsynchronousRequest 使用 @987654324 @ of queue 当您再次请求主队列时,它会被释放,因为您已经在主队列中。您可以检查您是否已经在主队列中,只需调用 serverCompletionHandler 否则 dispatch on mainqueue。在这种情况下,您可以跳过此检查你确定你是main queue,可以打电话给serverCompletionHandler()
[NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
// do stuff…
if([[NSOperationQueue currentQueue] isEqual:[NSOperationQueue mainQueue]]){ //check for main queue
if (serverCompletionHandler) {
serverCompletionHandler();
}
}
else{
if (serverCompletionHandler) { if not than dispatch on main queue
dispatch_async(dispatch_get_main_queue(), ^{ //No need to do that
serverCompletionHandler();
});
}
}];
编辑:感谢编辑的代码。正如您正在使用的那样
timer = [NSTimer scheduledTimerWithTimeInterval:10 target:self selector:@selector(createAndSendRequestWithCompletionHandler:) userInfo:nil repeats:YES];
现在你没有通过completionhandler,所以通过这样做createAndSendRequestWithCompletionHandler:计时器将自己传递给你的serverCompletionHandler。
所以serverCompletionHandler 本身包含timer 对象而不是任何block 对象。如果您尝试在requestWithRequest 中使用NSLog serverCompletionHandler,您会发现它是计时器对象。现在当dispatch_async 尝试调用serverCompletionHandler 时不阻塞就会崩溃。
这两行写在createAndSendRequestWithCompletionHandler中
NSLog(@"serverCompletionHandler obnj %@",serverCompletionHandler );
NSLog(@"class %@",NSStringFromClass([serverCompletionHandler class] ));
编辑 2
如果你真的想传递完成处理程序而不是传递计时器对象的userInfo。使用下面的代码
#import "YourViewController.h"
typedef void (^MyCompletionHandler)(void);
@interface YourViewController ()
{
NSTimer *timer;
}
@end
@implementation YourViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
if ([timer isValid]) {
[timer invalidate];
}
MyCompletionHandler com = ^{
NSLog(@"Hi this is completion handler");
};
timer = [NSTimer scheduledTimerWithTimeInterval:10 target:self selector:@selector(createAndSendRequestWithCompletionHandler:) userInfo:@{@"serverCompletionHandler":com} repeats:YES];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
-(void)requestWithRequest:(NSURLRequest*)request withCompletionHandler:(MyCompletionHandler)serverCompletionHandler{
[NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
// do stuff…
if (serverCompletionHandler) {
dispatch_async(dispatch_get_main_queue(), ^{
serverCompletionHandler();
});
}
}];
}
-(void)createAndSendRequestWithCompletionHandler:(NSTimer *)timerObj{
// NSLog(@"serverCompletionHandler obnj %@",serverCompletionHandler );
// NSLog(@"class %@",NSStringFromClass([serverCompletionHandler class] ));
//get completion handler from `userInfo`
NSMutableURLRequest* request = [[NSMutableURLRequest alloc] init];
[self requestWithRequest:request withCompletionHandler:timerObj.userInfo[@"serverCompletionHandler"]];
}
@end