通过分配弱指针到伊娃在一座座(Assignment to ivar in a Block via w

2019-06-26 00:59发布

我有一个只读属性isFinished在我的接口文件:

typedef void (^MyFinishedBlock)(BOOL success, NSError *e);

@interface TMSyncBase : NSObject {
     BOOL isFinished_;
}

@property (nonatomic, readonly) BOOL isFinished;

我想将它设置为YES后来在一些点块,而无需创建一个保留周期self

- (void)doSomethingWithFinishedBlock:(MyFinishedBlock)theFinishedBlock {
    __weak MyClass *weakSelf = self;
    MyFinishedBlock finishedBlockWrapper = ^(BOOL success, NSError *e) {
        [weakSelf willChangeValueForKey:@"isFinished"];
        weakSelf -> isFinished_ = YES;
        [weakSelf didChangeValueForKey:@"isFinished"];
        theFinishedBlock(success, e);
    };

    self.finishedBlock = finishedBlockWrapper; // finishedBlock is a class ext. property
}

我不确定这是做正确的方式。 请问这个代码泄露,或者休息,或者是罚款? 也许有我忽略了一个更简单的方法?

Answer 1:

传递块变量可以是零,检查之前调用或在函数的开头添加断言或者你会崩溃

既然你不保留自我,我们假设你的时候执行的后台线程一些艰巨的任务,你的代码获取的执行weakSelf可以是零(希望您使用ARC和5.0所以你niled弱引用)。

如果你没有真正的弱引用(<5.0,无电弧,编译器仍然会接受__weak但它不会有问题),这将导致崩溃。

“ - >”会导致崩溃,如果对象的指针是零,所以你需要确保它不发生也使用访问伊娃。

即使你做的代码dasblinkenlight写它可能会崩溃,如果weakSelf将是零的那一刻,让我们说你发送的块后台线程,然后前块的执行得到释放的对象,这使得weakSelf零因此,通过使用“accesing它 - >”会导致崩溃。 在这种情况下,如下我将修改代码:

__weak MyClass *weakSelf = self;
MyFinishedBlock finishedBlockWrapper = ^(BOOL success, NSError *e) {
    MyClass *strongSelf = weakSelf;
    //! whatever task you want executed
    strongSelf.isFinished = YES;
    theFinishedBlock(success, e);
};

此外,如果它没有任何意义,你可以测试是否weakSelf是零,以防止执行昂贵的任务(对象已毁)。 但是,这取决于使用情况。

但也有您需要的块编程时,例如考虑其他情况:你可以有一个作业对象实例的唯一作用是执行在后台的一些任务,在这种情况下,该代码可能会失败,因为您将创建新的任务,块上执行后台线程之前,在这种情况下,你应该保持自我,不要在对象保留块也可能被释放(这将防止保留周期)。



Answer 2:

轻微的解决方法是创建一个方法,让编译器为您处理。 做工精细,但我不知道这是否是正确的方法。 谁能告诉如果它的正确吗?

__weak MyClass *weakSelf = self;
MyFinishedBlock finishedBlockWrapper = ^(BOOL success, NSError *e) {
    [weakSelf makeIsFinishedYes];
};

- (void)makeIsFinishedYes
{
    isFinished_ = YES;
}


文章来源: Assignment to ivar in a Block via weak pointer