【问题标题】:Grand Central Dispatch - Passing data between threadsGrand Central Dispatch - 在线程之间传递数据
【发布时间】:2010-11-07 20:12:07
【问题描述】:

我正在尝试在后台运行一个进程以生成一个字符串,然后在主线程中使用该字符串(发送到远程服务器。)代码在模拟器中运行良好,并且该字符串被记录两次预期的。

在设备(iPad、4.2 和各种 iPhone)上,每次使用 EXC_BAD_ACCESS 都会崩溃。似乎 myString 超出了范围,但这似乎与使用相同原理的示例 on Wikipedia 背道而驰。

代码如下:

dispatch_async(_queue, ^{

 NSString *myString = [self generateString];
 NSLog(@"1 String is %@", myString);
 dispatch_async(dispatch_get_main_queue(), ^{
  NSLog(@"2 String is %@", myString);
 });

});

有谁知道为什么会崩溃,以及修复它的最佳方法?


我犯了一个错误,简化了我的代码以保持我的问题清晰。

在主队列上,我实际上通过另一个呼叫向自己发送消息,这会导致访问不正确。

解决方案是在我的异步队列上调用方法,并在方法内部将代码包装在 dispatch_async(dispatch_get_main_queue(), ^{});块。

希望这对其他人有帮助。

【问题讨论】:

  • 您的编辑表明您修复了症状,而不是问题。 Block 将始终保留它在复制时引用的所有对象,包括self

标签: objective-c grand-central-dispatch objective-c-blocks


【解决方案1】:

我犯了一个错误,简化了我的代码以保持我的问题清晰。

在主队列上,我实际上通过另一个呼叫向自己发送消息,这会导致访问不正确。

解决方案是在我的异步队列上调用方法,并在方法内部将代码包装在 dispatch_async(dispatch_get_main_queue(), ^{});块。

希望这对其他人有帮助。

【讨论】:

    【解决方案2】:

    我的猜测是 NSString 是一个自动释放对象,因此它会超出范围并在用于主队列代码块之前释放。尝试将保留/释放添加到 NSString:

    dispatch_async(_queue, ^{
    
     NSString *myString = [self generateString];
     [myString retain];
     NSLog(@"1 String is %@", myString);
     dispatch_async(dispatch_get_main_queue(), ^{
      NSLog(@"2 String is %@", myString);
      [myString release];
     });
    
    });
    

    【讨论】:

    • 好主意,但不正确。当块被 dispatch_async() 复制时,内部块将保留 myString。这些保留和释放应该是不必要的。
    猜你喜欢
    • 2011-11-24
    • 1970-01-01
    • 1970-01-01
    • 2012-05-09
    • 1970-01-01
    • 2011-07-28
    • 2023-03-25
    • 2018-10-06
    相关资源
    最近更新 更多