Ios 在ARC中,dealloc方法调用包含对自身弱引用的方法/块,结果为weakSelf=nil

Ios 在ARC中,dealloc方法调用包含对自身弱引用的方法/块,结果为weakSelf=nil,ios,objective-c,automatic-ref-counting,Ios,Objective C,Automatic Ref Counting,正如标题所述,在ARC模式下,当我使用自参考(弱以避免参考循环)定义块时: 在dealloc中,我将该块称为: - (void)dealloc { ... BOOL isNil = self.someBlock(); ... } 然后我发现isNil=YES 当我希望dealloc中的块与self一起做一些事情时,这似乎是一个问题 这种情况也发生在回调函数中,我在这里不给出示例 我的解决方案是使用“不安全”而不是“脆弱” 但这看起来很难看 有没有更好的方法来避免deal

正如标题所述,在ARC模式下,当我使用自参考(弱以避免参考循环)定义块时:

在dealloc中,我将该块称为:

- (void)dealloc {
    ...
    BOOL isNil = self.someBlock();
    ...
}
然后我发现isNil=YES

当我希望dealloc中的块与self一起做一些事情时,这似乎是一个问题

这种情况也发生在回调函数中,我在这里不给出示例

我的解决方案是使用“不安全”而不是“脆弱”

但这看起来很难看

有没有更好的方法来避免dealloc中的零弱自我

更新问题:为什么
weakSelf
为零,即使
self
为零?这是解除锁定的原因吗


为了清楚起见,我将测试代码粘贴到下面:

#import <Foundation/Foundation.h>

@interface blockWeak : NSObject

@property (nonatomic, strong) BOOL (^someBlock)();
@property (nonatomic) int num;

- (void)makeBlock;

@end

@implementation blockWeak

- (void)makeBlock
{
    typeof(self) __weak weakSelf = self;
    self.someBlock = ^(){
        typeof(self) strongSelf = weakSelf;
        strongSelf.num = 2;
        return weakSelf == nil?YES:NO;
    };
}

- (void)dealloc
{
    BOOL isNil = self.someBlock();
    if (isNil) {
        NSLog(@"weakSelf is nil.");
    }
}

@end

int main(int argc, const char * argv[])
{
    @autoreleasepool {
        blockWeak *bw = [[blockWeak alloc] init];
        bw.num = 1;
        [bw makeBlock];
    }
    return 0;
}
#导入
@接口块弱:NSObject
@性质(非原子,强)BOOL(^someBlock)();
@属性(非原子)int num;
-(void)makeBlock;
@结束
@实现阻塞弱
-(void)makeBlock
{
类型(自我)uu弱弱自我=自我;
self.someBlock=^(){
typeof(self)strongSelf=weakSelf;
strongSelf.num=2;
返回weakSelf==nil?是:否;
};
}
-(无效)解除锁定
{
BOOL isNil=self.someBlock();
if(isNil){
NSLog(@“weakSelf为零”);
}
}
@结束
int main(int argc,const char*argv[]
{
@自动释放池{
blockWeak*bw=[[blockWeak alloc]init];
bw.num=1;
[bw makeBlock];
}
返回0;
}

您不调用块。这将是:

BOOL isNil = self.someBlock();

以下内容有效,在我看来更清晰,因为没有提及
self
。 现在也不需要返回块的
BOOL
,但是我把它留在了

#import <Foundation/Foundation.h>

@interface blockWeak : NSObject

@property (nonatomic, copy) BOOL (^someBlock)(blockWeak *);
@property (nonatomic) int num;

- (void)makeBlock;

@end

@implementation blockWeak

- (void)makeBlock
{
    self.someBlock = ^BOOL(blockWeak *object){
        object.num = 2;
        return object == nil?YES:NO;
    };
}

- (void)dealloc
{
    NSLog(@"num = %d", _num);
    BOOL isNil = _someBlock(self);
    if (isNil) {
        NSLog(@"block returned NO");
    } else {
        NSLog(@"block returned YES");
    }
    NSLog(@"num = %d", _num);
}

@end

int main(int argc, const char * argv[])
{
    @autoreleasepool {
        blockWeak *bw = [[blockWeak alloc] init];
        bw.num = 1;
        [bw makeBlock];
    }
    return 0;
}

除了回答中提到的明显错误外,您的用例是什么?检查
dealloc
中的
weakSelf
是否已被nilled似乎不是您应该做的事情。真正的用例是,我需要块来执行一些清理工作,而不是在dealloc中释放内存,这可能会使用类的属性/ivar,甚至self。我对这个问题做了一些修改,让它更清楚。你可以在dealloc中调用任何东西,甚至可以使用self。我已经尝试过了。使用self是可以的。我将块上的代码复制到dealloc,它就可以工作了。但是,当您在dealloc中使用包含指向self的弱指针的块/函数时,它不起作用,因为当程序进入块/函数内部时,“weakSelf”变为nil。这就是我感到困惑的原因。对不起,我错了。忘记使用
self
作为
block
的参数是延迟
self
引用的好方法。但我仍然想知道为什么
weakSelf
dealoc
中为零。这很有帮助。谢谢
#import <Foundation/Foundation.h>

@interface blockWeak : NSObject

@property (nonatomic, copy) BOOL (^someBlock)(blockWeak *);
@property (nonatomic) int num;

- (void)makeBlock;

@end

@implementation blockWeak

- (void)makeBlock
{
    self.someBlock = ^BOOL(blockWeak *object){
        object.num = 2;
        return object == nil?YES:NO;
    };
}

- (void)dealloc
{
    NSLog(@"num = %d", _num);
    BOOL isNil = _someBlock(self);
    if (isNil) {
        NSLog(@"block returned NO");
    } else {
        NSLog(@"block returned YES");
    }
    NSLog(@"num = %d", _num);
}

@end

int main(int argc, const char * argv[])
{
    @autoreleasepool {
        blockWeak *bw = [[blockWeak alloc] init];
        bw.num = 1;
        [bw makeBlock];
    }
    return 0;
}
num = 1
block returned YES
num = 2