简体   繁体   English

可以访问self并在整个实例中使用的块

[英]Block that can access self and be used throughout an instance

I want a block that is available throughout a class, so it can be re-used many times by different methods in the instance. 我想要一个在整个类中都可用的块,因此它可以通过实例中的不同方法重复使用多次。

I want that block to be able to reference self. 我希望那个块能够引用自我。

I want to not have the block create any nasty retain cycles by retaining self. 我希望不要通过保留自我来创建任何讨厌的保留周期。

So far I am stumped. 到目前为止,我很难过。 I managed to create block in the .m outside of any method definitions, and that got me partway - I could reuse the block everywhere, but I couldn't access self. 我设法在任何方法定义之外的.m中创建块,这让我中途 - 我可以在任何地方重用块,但我无法访问自己。 I tried putting the block into an ivar but I'm doing something wrong there and now I'm getting random EXC_BAD_ACCESS. 我尝试将块放入ivar但我在那里做错了,现在我得到随机的EXC_BAD_ACCESS。 Can someone explain it simply, line by line? 有人可以简单地逐行解释吗?

Try the following: 请尝试以下方法:

typedef void (^MyBlock)();

@implementation MyClass
{
    MyBlock block;
}

- (id) init
{
   self = [super init];
   if (!self)
      return nil;

   __block MyClass* _self = self;

   block = [^ {
       [_self sendSomeMsg];
   } copy];
}

Note the __block storage type. 请注意__block存储类型。 Quoting this : "At function level are __block variables. These are mutable within the block (and the enclosing scope) and are preserved if any referencing block is copied to the heap." 引用 :“在功能水平是__block变量这些是块内的可变(和封闭的范围),并且如果任何参考块被复制到堆被保留。”。

This idiom may help you to remove the exc_bad_access (ARC code). 这个习惯用法可以帮助你删除exc_bad_access(ARC代码)。

// get a weak reference to self
__weak id weakSelf = self;
block = ^()
{
    // now the block is executing so we get a strong reference to self
    // (this prevents self from disappearing until the block is done executing)
    id strongSelf = weakSelf;
    if (strongSelf != nil)
    {
        // do whatever work you intended for this block
    }
};

I figured it out. 我想到了。

In MyClass.h: 在MyClass.h中:

typedef void (^DefaultFailureBlock)();

@property (copy) DefaultFailureBlock defaultFailureBlock;

in the init method: 在init方法中:

__block MyClass *selfReq = self;
self.defaultFailureBlock = ^{
    //use selfReq instead of self in here.
};

Interestingly, if you accidentally refer to self inside the block, you will have a retain cycle, and Analyze will not complain. 有趣的是,如果你不小心在块内引用self,你将有一个保留周期,Analyze不会抱怨。 I put an NSLog in dealloc to prove that it is actually being dealloced, and it is. 我在dealloc中放了一个NSLog来证明它实际上已经被释放了,它确实是。

Oh and don't forget to [defaultFailureBlock release]; 哦,别忘了[defaultFailureBlock release]; in dealloc too... 在dealloc中......

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM