As the title states, in ARC mode, when I define a block using self reference (weak to avoid reference cycle):
...
id __weak weakSelf = self;
self.someBlock = ^(){
if (weakSelf != nil){
(do something with weakSelf...)
return NO;
}
return YES;
};
...
In dealloc I call the block:
- (void)dealloc {
...
BOOL isNil = self.someBlock();
...
}
Then I found isNil = YES.
When I want blocks in dealloc to do something with self, this seems to be a problem.
This also happen in callback functions, which I will not give an example here.
My solution is using __unsafe_unretained instead of __weak.
But this looks ugly.
Is there better ways to avoid nil weak self in dealloc?
Updated Question: Why weakSelf
is niled even when self
is not? Is it the reason of dealloc
?
To make it clear, I paste the test code below:
#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;
}
weakSelf
has been already nilled indealloc
doesn't seem to be something you should have to do. – Sulthan