我是否需要复制传递到GCD块的块

时间:2015-08-10 17:02:02

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

我是否需要将块 requestSuccessBlock(data)/ requestFailureBlock(error)复制到堆中,这些块作为参数传递给GCD函数 dispatch_async(queue,block) 在以下代码中: -

//NSURLSession dataTaskWithURL method here
[[_urlSession dataTaskWithURL:url completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {

        dispatch_async(dispatch_get_main_queue(), ^{
            requestSuccessBlock(data);
        });

        dispatch_async(dispatch_get_main_queue(), ^{
            requestFailureBlock(error);
        });
    }
}] resume];

3 个答案:

答案 0 :(得分:0)

假设dataTaskWithUrl:completionHandler:将Block_copy()传递给你的块文字。

块本身是引用计数对象。因此completionHandler块将保留对它们的引用,因此您不需要进行任何手动内存管理,即使我假设您已将requestSuccessBlockrequestFailureBlock声明为封闭的本地人范围。

我确实认为你在完成时调用成功和失败块很奇怪,但我认为这只是为了说明目的。

答案 1 :(得分:0)

您可以将完成块视为闭包。它将捕获已从中传递完成处理程序的方法的整个上下文。

不,你不是。

答案 2 :(得分:0)

复制块时,它会保留所有捕获的指针到对象类型的变量,并对所有捕获的指针到块类型的变量进行块复制。 requestSuccessBlockrequestFailureBlock是指向块类型的变量,由传递给dataTaskWithURL:completionHandler:的大块捕获。所以问题实际上归结为,您是否需要复制传递给dataTaskWithURL:completionHandler:的块。

内存管理规则通常是本地的。这意味着,您不需要知道(也不应该关心)另一种方法的作用,因为您可以在自己的方法中正确使用内存管理。由于dataTaskWithURL:completionHandler:方法在一个指针到块类型的参数中获取块,如果它需要存储块以供以后异步使用,它必须复制它(我们可以猜测它是异步的名称在这种情况下,但我们不需要知道这一点)。就调用方法而言,该方法是同步还是异步使用块无关紧要;它只需要确保块在传递时有效,其余的是被调用方法的责任。

由于您自己的方法本身并不存储块供以后使用,答案是,您无需复制它们。