【问题标题】:How to save data out of an iOS completion block如何从 iOS 完成块中保存数据
【发布时间】:2012-08-08 17:52:23
【问题描述】:

我基本上是在实现一个更高级的 NSURLConnection 类,它从服务器下载数据并将其解析为字典,并返回数据的 NSDictionary。我正在尝试添加一个完成块选项(除了委托选项),但是每当我尝试将该数据存储在另一个类中时它都会崩溃。

        [dataFetcher_ fetchDataWithURL:testURL completionHandler:^(NSDictionary *data, NSInteger error) {        
            contentDictionary_ = data;            
    }];

我可以很好地 NSLog 那些数据,基本上可以用它做任何我想做的事情,但是一旦我尝试将它保存到另一个变量中,它就会崩溃并显示一条非常模糊的消息。

编辑:崩溃消息是 EXC_BAD_ACCESS,但堆栈跟踪是 0x00000000 错误:地址不包含指向目标文件中某个部分的部分。

我在单例的 init 方法中调用这个函数。如果我在完成块中设置它,它确实让我保存数据。

[SingletonClass sharedInstance].contentDictionary = data

但是随后应用程序永远卡住了,因为 sharedInstance 还没有返回,所以单例对象仍然是 nil,所以完成块中的 sharedInstance 再次调用 init,一遍又一遍。

编辑 2:单例代码如下所示:

+ (SingletonClass*)sharedInstance {
   static SingletonClass *instance;
   if (!instance) {
       instance = [[SingletonClass alloc] init];
   }
   return instance;
}


- (id)init {
    self = [super init];
    if (self) {
        dataFetcher_ = [[DataFetcher alloc] init];
        NSString *testURL = @"..."  
        [dataFetcher_ fetchDataWithURL:testURL completionHandler:^(NSDictionary *data, NSInteger error) {        
            [SingletonClass sharedInstance].contentDictionary = data;

        }];

    }
    return self;
}

就像我说的那样,这可以正常工作,但会一遍又一遍地重复初始化代码,直到应用程序崩溃。这只发生在我第一次在设备上运行应用程序时,因为我缓存了返回的数据,并且一旦我缓存了数据,它就不会崩溃。我希望能够只说 self.contentDictionary = data,但这会崩溃。

【问题讨论】:

  • 真正晦涩的信息是什么?该信息可能与遇到相同问题的人或知道解决方案的人有关。
  • 什么是contentDictionary_?实例变量?局部变量?
  • 听起来你的单例初始化器有问题。你能发布你的单例是如何存储的,以及它是如何初始化的吗?
  • 我更新了帖子以显示单身人士。 contentDictionary 是一个 ivar,如果它的 __block NSDictionary 或只是 NSDictionary 似乎没有什么区别。

标签: ios objective-c-blocks


【解决方案1】:

用块外的 __block 指令指定要在块中使用的变量:

__block NSDictionary *contentDictionary_;

[dataFetcher_ fetchDataWithURL:testURL completionHandler:^(NSDictionary *data, NSInteger error) {        
    contentDictionary_ = data;            
}];

【讨论】:

  • 我以为可能是这样,但我仍然遇到同样的崩溃。我实现 fetchDataWithURL 方法的方式有问题吗?
【解决方案2】:

您在设置“实例”之前调用了递归。 (我现在看到你从 OP 中理解)。

在您的块中,您可以使用 ivar 或访问器来代替

[SingletonClass sharedInstance].contentDictionary

使用: _contentDictionary = [data copy];self.contentDictionary=data; 假设支持 contentDictionary 属性的 ivar 是 _contentDictionary。

听起来您尝试了 self.contentDictionary 但失败了?我让它在测试中工作,转过 ARC,所以可能有一些关于你的 dataFetcher 的东西会影响这个。在我的测试中,dataFetcher 只返回一个包含单个元素的字典。

【讨论】:

  • 看来这可能是我的数据提取器的问题。大家的建议我都试过了,都没有奏效,所以可能是别的问题。
【解决方案3】:

原来问题出在一堆不同的部分上。我的 URL 有时是空的,我的数据获取器会立即失败并调用完成块。在我的完成块中,我没有包含任何错误处理,所以如果单例类没有初始化,它将永远重复。使用真实的 URL 不会发生这种情况。

不过,我仍然想弄清楚为什么当我尝试将数据分配给 ivar 时它会崩溃。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多