我目前正在研究使用许多 block 的实现。每一个区 block 都需要与自己沟通。
目前我正在这样做:
@implementation Foo
- (void) bar
{
__weak Foo *weakSelf = self;
[self doBlockStuff:^(id something) {
[weakSelf doSomething];
}];
}
@end
我有很多函数对弱实例化做同样的事情。
在接口(interface) block 中一次实例化弱属性并在所有地方使用它是否正确?
这是有效的,但这是一种公认的做法吗?
@interface Foo ()
{
__weak Foo *_weakSelf;
}
@end
@implementation Foo
-(instancetype) init
{
self = [super init];
if(self) {
_weakSelf = self;
}
return self;
}
- (void) bar1
{
[self doBlockStuff:^(id something) {
[_weakSelf doSomething];
}];
}
- (void) bar2
{
[self doBlockStuff:^(id something) {
[_weakSelf doSomething];
}];
}
- (void) bar3
{
[self doBlockStuff:^(id something) {
[_weakSelf doSomething];
}];
}
- (void) bar4
{
[self doBlockStuff:^(id something) {
[_weakSelf doSomething];
}];
}
@end
使用新信息测试后编辑: 我确实写了一个小测试用例,现在我可以证明为什么第二个测试用例不起作用。 在我的测试类中,我在 5 秒后使用相关的 self 使用进行调度,并在我的 dealloc 被调用时记录下来。
@implementation Foo
- (void)dealloc
{
NSLog(@"dealloc");
}
- (instancetype)init
{
self = [super init];
if (self) {
}
return;
}
- (void)bar
{
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[self doSomething];
});
}
@end
如果类失去持有者,因为 Controller 关闭或其他原因而函数仍在运行,类将在调度完成后进行对话。
@interface Foo ()
{
__weak Foo *_weakSelf;
}
@end
@implementation Foo
- (void)dealloc
{
NSLog(@"dealloc");
}
- (instancetype)init
{
self = [super init];
if (self) {
_weakSelf = self;
}
return;
}
- (void)bar
{
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[_weakSelf doSomething];
});
}
@end
如果分派(dispatch)完成,这个也会 dealloc。因为 _weakSelf 属性仍然被类打洞,这是使用 self->_weak 的简写。 self 意味着 self :)
@implementation Foo
- (void)dealloc
{
NSLog(@"dealloc");
}
- (instancetype)init
{
self = [super init];
if (self) {
}
return;
}
- (void)bar
{
__weak typeof(self) weakSelf = self;
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[weakSelf doSomething];
});
}
@end
这个会立即解除分配,因为弱引用只存在于给 block 的这个函数中。该函数结束,如果该类丢失了他的引用,则该 block 没有任何属性可以挖空任何人。但是 weak 属性在引用类可用时仍然可用。 可以肯定的是,这个弱属性会存在,我们可以在区 block 中设置一个强循环。
最佳答案
这根本不是您认为的那样。那些方法中的 __weak
实例变量?这只是 self->_weak
的简写。所有这些使用建议方式的方法仍然强烈地捕获 self
。
坚持之前的做法。
关于ios - __ block 的弱通用变量声明,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27314731/