Ale*_*der 19 objective-c ios objective-c-blocks automatic-ref-counting retain-cycle
我需要阻止.但编译器会发出警告
"在这个区块强势捕捉'自我'可能会导致保留周期"
__weak typeof(self) weakSelf = self;
[generalInstaImage setImageWithURLRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:data[@"images"][@"low_resolution"][@"url"]]] placeholderImage:[UIImage imageNamed:@"Default"] success:^(NSURLRequest *request, NSHTTPURLResponse *response, UIImage *image) {
NSLog(@"success");
[generalInstaImage setImage: image];
[weakSelf saveImage:generalInstaImage.image withName:data[@"id"]];
} failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error) {
NSLog(@"fail");
}];
Run Code Online (Sandbox Code Playgroud)
我尝试编写类似的例子weakSelf.generalInstaImage,但编译器生成错误而不编译.
Rob*_*Rob 61
考虑这个警告:
self在该块中强烈捕获可能导致保留周期
当您收到上述警告时,您应该检查您的阻止:
self; 要么self引用任何实例变量引起的任何隐式引用.让我们假设我们有一个简单的类属性是一个块(这会遇到与你的问题相同的"保留周期"警告,但会使我的例子更简单一些):
@property (nonatomic, copy) void (^block)(void);
Run Code Online (Sandbox Code Playgroud)
我们假设我们想要在块中使用其他类属性:
@property (nonatomic, strong) NSString *someString;
Run Code Online (Sandbox Code Playgroud)
如果您self在块中引用(在下面的示例中,在访问此属性的过程中),您显然会收到有关保留周期风险的警告:
self.block = ^{
NSLog(@"%@", self.someString);
};
Run Code Online (Sandbox Code Playgroud)
这可以通过您建议的模式来解决,即:
__weak typeof(self) weakSelf = self;
self.block = ^{
NSLog(@"%@", weakSelf.someString);
};
Run Code Online (Sandbox Code Playgroud)
不太明显的是,如果引用块内类的实例变量,您还会收到"保留周期"警告,例如:
self.block = ^{
NSLog(@"%@", _someString);
};
Run Code Online (Sandbox Code Playgroud)
这是因为_someString实例变量带有一个隐式引用self,实际上等同于:
self.block = ^{
NSLog(@"%@", self->_someString);
};
Run Code Online (Sandbox Code Playgroud)
你可能也倾向于尝试在这里采用弱自我模式,但你不能.如果您尝试weakSelf->_someString语法模式,编译器将警告您:
__weak由于竞争条件可能导致空值,因此不允许取消引用指针,首先将其分配给strong变量
因此,您可以通过使用weakSelf模式来解决此问题,还可以strong在块中创建局部变量并使用它来取消引用实例变量:
__weak typeof(self) weakSelf = self;
self.block = ^{
__strong typeof(self) strongSelf = weakSelf;
if (strongSelf) {
NSLog(@"%@", strongSelf->_someString);
// or better, just use the property
//
// NSLog(@"%@", strongSelf.someString);
}
};
Run Code Online (Sandbox Code Playgroud)
顺便说一句,在块内创建本地strong引用strongSelf也有其他优点,即如果完成块在不同的线程上异步运行,则不必担心self在块执行时被释放,导致意想不到的后果.
此weakSelf/ strongSelf模式在处理块属性时非常有用,并且您希望阻止保留周期(也称为强引用周期),但同时确保self在完成块的执行过程中无法释放.
仅供参考,Apple 在过渡到ARC发行说明的" 使用生命周期限定符以避免强引用周期"部分的"非平凡周期"讨论中讨论了这种模式.
您报告weakSelf.generalInstaImage在示例中引用时收到了一些"错误" .这是解决此"保留周期"警告的正确方法,因此如果您收到某些警告,您应该与我们分享,并告诉我们您如何申报该财产.
| 归档时间: |
|
| 查看次数: |
18597 次 |
| 最近记录: |