__weak块的通用变量声明

时间:2014-12-05 11:18:44

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

我目前正在开发一个使用了很多块的实现。每个街区都需要与自己沟通。

目前我这样做:

@implementation Foo
- (void) bar
{
    __weak Foo *weakSelf = self;
    [self doBlockStuff:^(id something) {
        [weakSelf doSomething];
    }];
}
@end

我有许多函数可以对弱实例化做同样的事情。

在接口块中实例化一次弱属性并在任何地方使用它是否正确?

它正在运作,但这是一种公认​​的做法吗?

@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

使用新信息进行测试后修改 我写了一个小测试用例,现在我可以证明为什么第二个不能正常工作。 在我的Testclass中,在5秒后使用相关的自我使用进行一次调度,并在调用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

如果班级失去了持有人,因为控制器已关闭或其他任何功能仍在运行,该班级将在调度完成后拨打。

@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

如果调度完成,这个也将在dealloc上。因为_weakSelf属性仍然是类,所以使用self-> _weak的简写。自我意味着自我:)

@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

这个将立即释放,因为弱引用仅存在于给予块的此函数中。该功能已经结束,如果该类失去了他的引用,那么该块没有任何属性的东西。但是当引用类可用时,弱属性仍然可用。 可以肯定的是,这个弱小的属性将会存在,我们可以在块中设置一个强大的循环。

2 个答案:

答案 0 :(得分:2)

这根本不符合你的想法。那些方法中的那个__weak实例变量?这只是self->_weak的简写。所有使用提议方式的方法仍然强烈地捕获self

坚持你以前做过的事情。

答案 1 :(得分:-1)

如果__weakSelf仍然拥有强引用,那么这真的很糟糕。问题是,如果在方法中实例化并在方法中使用它,它仍然真的对自己有一个弱锚或者它在那个时刻持有强引用。根据文档,您可以在块外实例化弱引用,如果需要,甚至可以在块内强化它。看看这里

http://aceontech.com/objc/ios/2014/01/10/weakify-a-more-elegant-solution-to-weakself.html

我现在的问题是,为什么一个弱的自我实例化会在真正的自我释放时解除它的自我...?因为我试图在另一个viewController中保持弱自我,然后释放真正的自我。但是,一旦我解除了真正的自我,弱者就会被释放。