在块内调用类级别代码会导致目标c崩溃

时间:2015-10-16 08:34:30

标签: ios objective-c block

我有一个函数调用get服务并将数据返回到一个块,该块作为参数传递给函数。 我已经创建了一个通用的块函数处理程序,它可以将任何块作为参数,它有两个变量作为参数。一个是BOOL,另一个是id。

问题是,如果我在调用函数'中添加包含包含类级别函数/属性的代码的任何行。然后代码在调用中被称为函数'

调用功能

-(void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];
    Controller * __weak controller = self;

    [network getWithBlock:(__bridge void *)(^(BOOL isSuccess, id responseData)
     {
         if(isSuccess)
         {
             NSLog(@"Successful Get");
             NSDictionary *data = responseData;
             if(data == nil)
             {
             }
             else
             {
                 NSLog(@"It is working %@");
                 [self emptyFunction];  // [controller emptyFunction];                 
             }
         }
         else
         {
             NSLog(@"Failure");
         }
     })];
}

被叫函数

- (void) getWithBlock:(void *) block
{
    //some code
    NSURLSessionDataTask *postDataTask = [session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error)
       {
           NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response;
           void (^responseBlock)(BOOL isSuccess,id object) = (__bridge_transfer typeof(responseBlock)) block;
//some response conversion into dict

           dispatch_async(dispatch_get_main_queue(), ^{
               responseBlock(YES, dict);
           });
     }];

    [postDataTask resume];

}

问题

问题是,如果我评论行[self emptyFunction]块已执行且没有崩溃。但是如果我取消注释该行或添加包含控制器的变量/类级变量(调用控制器)的任何其他行,则在调度行处的调用函数处发生崩溃。

我尝试了各种方法。在viewDidAppear中调用它。对控制器进行弱引用然后调用函数但没有用。

我无法理解为什么在块中调用类级变量会导致错误。

1 个答案:

答案 0 :(得分:0)

使用__bridge_transfer有错误。 __bridge_transfer消耗保留计数。但是,您从未对该块对象进行不平衡的保留。所以这可能会导致过度释放。您应该将其更改为仅__bridge

此外,您应该将演员从void *(非托管指针类型)移回块类型到发送到dataTaskWithRequest:的块的外部,因为块需要知道它&# 39;捕获块类型的变量,以便在复制它本身时正确复制它。