ios - 如何正确实现嵌套 block ? ios

标签 ios objective-c objective-c-blocks

通过这个类我发送 http 请求:

     @interface AsyncRequest()
        @property(strong,nonatomic)NSURLRequest* murlRequest;
        @property(copy) OnCompleted onCompletedBlock;
        @end
        @implementation AsyncRequest
        //Async Request object initialization
        -(instancetype)initWithUrl:(NSString*)urlRequest onCompletedBlock:(OnCompleted) onCompeletedBlock
        {
            self = [super init];
            if(self)
            {
                //blocks


                NSURL* url  = [NSURL URLWithString:[NSStringstringWithFormat:@"%@%@",SERVER_URL,urlRequest]];

                self.onCompletedBlock = onCompeletedBlock;
                self.murlRequest = [NSURLRequest requestWithURL:url];
            }
            return self;
        }
    //call this function to execute the specified request
    -(void)ExecuteRequest
    {
        AsyncRequest * __weak weakself = self;

       //localVariable is used by value, a strong reference is made to localVariable in the block
        NSURLRequest *urlRequest = self.murlRequest;
        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0),^(void){
            NSURLResponse *response = nil;
            NSError *error = nil;
            NSData * data = [NSURLConnection sendSynchronousRequest:urlRequest returningResponse:&response error:&error];
                    //main ui
                    dispatch_async(dispatch_get_main_queue(),^{
                                weakself.onCompletedBlock(data);
                    });
    }
        @end

所以我声明了 onComplete block 并在 initWithUrlFunction 中初始化它们,然后我使用 weakself 来运行它。

但问题是我在 weakself.onCompletedBlock(data) ->

处遇到了这个错误

Thread1:EXC_BAD_ACCESS(code=2,address=0xc)

有什么问题吗?

最佳答案

您需要先将 weakself.onCompletedBlock 分配给一个强变量,并在调用它之前测试它不是 nil


你需要在调用它之前测试 block 不是nil,除非你能保证它不会是nil。或者您的应用程序像您一样崩溃并出现糟糕的错误消息。与 nil 对象上的 invoke 方法完全安全不同,调用 nil block 将导致取消引用无效的内存地址。

block() 将被编译成类似 block->someFunction(block->someStruct) 的东西,如果 block NULL/0,你会遇到 C++ 风格的崩溃。


您不想多次访问 __weak 变量。您必须将它分配给一个 __strong 变量然后访问它。否则可能会因为没有保留而意外释放。

__weak Foo *obj = // something
[obj dowork];   // obj may be valid value at this point
[obj dootherwork]; // obj may be nil here even previous call success
id foo = obj->somevar;  // may crash with dereference invalid memory address

你需要做的是

__weak Foo *obj = // something
Foo *strongObj = obj;
if (strongObj) { // not always required
    // you know strongObj is retained and will not be released until it go out of scope
    // so you can access strongObj safely without surprise 
}

关于ios - 如何正确实现嵌套 block ? ios,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25503920/

相关文章:

ios - 将自定义字体嵌入从iPad应用程序生成的PDF中

ios - 我如何找到一个结构占用了多少内存?

c - 关于在 Objective-c 堆上分配 c 结构和数组所需的指南

Objective-c: block 和 NSEnumerationConcurrent 的问题

ios - 将 block 存储在实例变量中有什么用

c++ - Objective-C block 和 C++ 对象

ios - 电话:在 ios 13 中显示为操作表的 url 方案?

iphone - 直接使用 UIViewControllers.view 或 UIView 的内存消耗

ios - 无法从 Localizable.strings 文件中检索本地化字符串

iphone - 修改 UIBezierPath 的图案透视图