参考自我内部块 [英] Reference to self inside block

查看:201
本文介绍了参考自我内部块的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

现在我有一部分代码如下:

Right now I have a portion of code like this:

__strong MyRequest *this = self;

 MyHTTPRequestOperation *operation = [[MyHTTPRequestOperation alloc]initWithRequest:urlRequest];
 [operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *request, id responseObject) {
     [this requestFinished:request];
 }
 failure:^(AFHTTPRequestOperation *request, NSError *error) {
     [this requestFailed:request withError:error];
 }];

我主要是这样做的,因为其他一些类继承自此代码所在的类并实现他们自己的requestFinished和requestFailed。

I am mainly doing this because some other classes are inheriting from the class where this code is located and implementing their own requestFinished and requestFailed.

如果我将自引用更改为__weak,我开始收到一些EXC_BAD_ACCESS错误。使用__strong引用一切正常,但我担心创建一个保留周期。
请注意我正在使用ARC。

If I change the self reference to __weak I start getting some EXC_BAD_ACCESS errors. With a __strong reference everything works fine but I'm afraid about creating a retain cycle. Note that i am using ARC.

此代码是否会创建一个会导致问题的保留周期?任何简单的解决方案?我可以遵循的任何不同方法让继承类实现自己的方法来处理响应吗?

Is this code creating a retain cycle that will cause problems? Any simple solution to this? Any different approach that I can follow to let inheriting classes implement their own methods to handle responses?

推荐答案

是的,它会创建一个保留周期。它会导致问题吗?也许。

Yes, it creates a retain cycle. Does it cause problems? Maybe.

如果API支持它,你可以重置处理程序,这将手动打破保留周期:

If the API supports it, you can reset the handlers, which will break the retain cycle manually:

[operation setCompletionBlockWithSuccess:nil failure:nil];

或者您可以使用弱引用。但是,你说你尝试了一个弱引用,它就崩溃了。弱引用保证在消息开头处为nil,或者在消息处理之前保持有效。换句话说,考虑......

Or you can use a weak reference. However, you say you tried a weak reference, and it crashed. A weak reference is guaranteed to be either nil at the start of a message, or remain valid until the message has been processed. In other words, consider...

__weak MyRequest *weakSelf = self;
dispatch_async(someQ, ^{
    [weakSelf doSomething];
});

如果 weakSelf 在异步块时为nil执行,然后没有发生。如果它不是零,则保证至少保留至 doSomething 结束。实际上,它类似于:

If weakSelf is nil when the asynchronous block executes, then "nothing" happens. If it is not nil, then it is guaranteed to be retained at least until doSomething has finished. In effect, it is similar to this:

__weak MyRequest *weakSelf = self;
dispatch_async(someQ, ^{
    { id obj = weakSelf; [weakSelf doSomething]; obj = nil; }
});

但是,请注意,如果你这样做:

Note, however, that if you did this:

__weak MyRequest *weakSelf = self;
dispatch_async(someQ, ^{
    [weakSelf doSomething];
    [weakSelf doSomethingElse];
});

该对象可以在 doSomething doSomethingElse

此外,如果您通过弱引用访问实例变量,那么您只需要询问对于SEGV:

Furthermore, if you access an instance variable via a weak reference, you are just asking for a SEGV:

__weak MyRequest *weakSelf = self;
dispatch_async(someQ, ^{
    foo = weakSelf->someIVar; // This can go BOOM!
});

因此,如果您的处理程序正在访问单个消息的弱引用,那么您应该没问题。其他任何东西都应该做弱强舞。

Thus, if your handler is accessing the weak reference for a single message, then you should be fine. Anything else should do the "Weak-Strong-Dance."

__weak MyRequest *weakSelf = self;
dispatch_async(someQ, ^{
    MyRequest *strongSelf = weakSelf;
    if (!strongSelf) return;
    [strongSelf doSomething];
    [strongSelf doSomethingElse];
    foo = strongSelf->someIVar;
});

如果您认为您遵守了这些指导原则,那么可能是一个更完整的源代码示例细节会有所帮助......

If you think you are following the guidelines, then maybe a more complete source code example, with the crash details would help...

这篇关于参考自我内部块的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆