ios - __ block 的弱通用变量声明

标签 ios objective-c iphone automatic-ref-counting

我目前正在研究使用许多 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/

相关文章:

iphone - 使用动画 block 移动原点调整 UIScrollView 的大小

ios - 添加到 UITableView 时在 Storyboard 中使用 UITableViewCells 的正确方法是什么

ios - 为 AFNetworking 2.0 URL 字符串正确转义字符

objective-c - 如何使用 google contacts api 在 iOS 应用程序中获取 gmail 联系人?

iphone - 单击 UIAlertView 时崩溃

ios - UITableView:删除行和添加新行后,新行不可选择

ios - 将字符串转换为时间格式将返回nil数据

ruby-on-rails - SHA1 哈希值在我的 Rails 和 Cocoa 应用程序之间不匹配

ios - CallKit 扩展开始请求

ios - 如何以编程方式设置 wC hR 字体大小?