总是将自我的弱引用传递给ARC中的块?
我对Objective-C中的块使用有点困惑。 我目前使用ARC,并且在我的应用中有相当多的块,现在总是指self
而不是它的弱引用。 这可能是这些块保持self
并防止它被交易的原因吗? 问题是,我应该总是在一个块中使用self
的weak
引用吗?
-(void)handleNewerData:(NSArray *)arr
{
ProcessOperation *operation =
[[ProcessOperation alloc] initWithDataToProcess:arr
completion:^(NSMutableArray *rows) {
dispatch_async(dispatch_get_main_queue(), ^{
[self updateFeed:arr rows:rows];
});
}];
[dataProcessQueue addOperation:operation];
}
ProcessOperation.h
@interface ProcessOperation : NSOperation
{
NSMutableArray *dataArr;
NSMutableArray *rowHeightsArr;
void (^callback)(NSMutableArray *rows);
}
ProcessOperation.m
-(id)initWithDataToProcess:(NSArray *)data completion:(void (^)(NSMutableArray *rows))cb{
if(self =[super init]){
dataArr = [NSMutableArray arrayWithArray:data];
rowHeightsArr = [NSMutableArray new];
callback = cb;
}
return self;
}
- (void)main {
@autoreleasepool {
...
callback(rowHeightsArr);
}
}
这不仅有助于把重点放在strong
或weak
的讨论的一部分。 而是专注于周期部分。
保留周期是当对象A保留对象B并且对象B保留对象A时发生的循环。在这种情况下,如果任一对象被释放:
因此,这两个对象只会在程序的整个生命周期中留存下来,尽管如果一切正常,它们应该被释放。
所以,我们担心的是保留周期,并且没有任何关于自己创建这些周期的块。 这不是一个问题,例如:
[myArray enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop){
[self doSomethingWithObject:obj];
}];
该块保留self
,但self
不保留该块。 如果一个或另一个被释放,则不会创建循环,并且所有内容都应该被释放。
你遇到麻烦的地方就像是:
//In the interface:
@property (strong) void(^myBlock)(id obj, NSUInteger idx, BOOL *stop);
//In the implementation:
[self setMyBlock:^(id obj, NSUInteger idx, BOOL *stop) {
[self doSomethingWithObj:obj];
}];
现在,你的对象( self
)对块有明确的strong
引用。 该块对self
有一个隐含的强烈的参照。 这是一个循环,现在这两个对象都不会被正确释放。
因为,在这样的情况下, self
定义已经具备了strong
参考块,它通常是最容易通过做一个明确的弱引用来解决self
的块使用:
__weak MyObject *weakSelf = self;
[self setMyBlock:^(id obj, NSUInteger idx, BOOL *stop) {
[weakSelf doSomethingWithObj:obj];
}];
但是,这不应该是你在处理self
块时遵循的默认模式 ! 这应该只用于打破本来和块之间的保留周期。 如果你在任何地方都采用这种模式,那么你会冒着将self
被释放后被执行的东西传递给块的风险。
//SUSPICIOUS EXAMPLE:
__weak MyObject *weakSelf = self;
[[SomeOtherObject alloc] initWithCompletion:^{
//By the time this gets called, "weakSelf" might be nil because it's not retained!
[weakSelf doSomething];
}];
你不必总是使用弱引用。 如果你的块没有被保留,但被执行然后被丢弃,你可以强烈地捕获自己,因为它不会创建保留周期。 在某些情况下,你甚至希望块保持自己,直到块完成,所以它不会过早地解除分配。 但是,如果您强烈地捕获该块,并在捕获自我内部,它将创建一个保留周期。
我完全同意@jemmons。
“但是,这不应该是你在处理自称的块时遵循的默认模式!这应该只用于打破本来和块之间的保留循环,如果你想在每个地方采用这种模式,那么冒着将自己被释放后被执行的东西传递给自己的风险。“
//SUSPICIOUS EXAMPLE:
__weak MyObject *weakSelf = self;
[[SomeOtherObject alloc] initWithCompletion:^{
//By the time this gets called, "weakSelf" might be nil because it's not retained!
[weakSelf doSomething];
}];
为了解决这个问题,人们可以定义一个关于块内部weakSelf的强有力的参考。
__weak MyObject *weakSelf = self;
[[SomeOtherObject alloc] initWithCompletion:^{
MyObject *strongSelf = weakSelf;
[strongSelf doSomething];
}];
链接地址: http://www.djcxy.com/p/37673.html