如何将数据保存在iOS完成块之外

时间:2012-08-08 17:52:23

标签: ios objective-c-blocks

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

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

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

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

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

[SingletonClass sharedInstance].contentDictionary = data

然后应用程序永远陷入困境,因为sharedInstance尚未返回,因此单例对象仍为零,因此完成块中的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,但崩溃了。

3 个答案:

答案 0 :(得分:0)

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

__block NSDictionary *contentDictionary_;

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

答案 1 :(得分:0)

您在设置"实例"之前调用递归。 (我现在看到你从OP了解到这一点。)

在您的区块中,您可以使用ivar或访问者而不是

[SingletonClass sharedInstance] .contentDictionary

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

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

答案 2 :(得分:0)

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

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