我有一个只读属性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
}
我不确定这是做正确的方式。 请问这个代码泄露,或者休息,或者是罚款? 也许有我忽略了一个更简单的方法?
传递块变量可以是零,检查之前调用或在函数的开头添加断言或者你会崩溃
既然你不保留自我,我们假设你的时候执行的后台线程一些艰巨的任务,你的代码获取的执行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是零,以防止执行昂贵的任务(对象已毁)。 但是,这取决于使用情况。
但也有您需要的块编程时,例如考虑其他情况:你可以有一个作业对象实例的唯一作用是执行在后台的一些任务,在这种情况下,该代码可能会失败,因为您将创建新的任务,块上执行后台线程之前,在这种情况下,你应该保持自我,不要在对象保留块也可能被释放(这将防止保留周期)。
轻微的解决方法是创建一个方法,让编译器为您处理。 做工精细,但我不知道这是否是正确的方法。 谁能告诉如果它的正确吗?
__weak MyClass *weakSelf = self;
MyFinishedBlock finishedBlockWrapper = ^(BOOL success, NSError *e) {
[weakSelf makeIsFinishedYes];
};
- (void)makeIsFinishedYes
{
isFinished_ = YES;
}