Why does not access self-declaration, warns the compiler in a block owned by itself
I am a little confused about the memory management / save loops. Here's a simple class:
@interface Test : NSObject {
NSObject *objectA;
}
@property (nonatomic, strong) NSObject *objectB;
- (void)methodA;
@end
Let's say I have a block owned by an instance of Test. In this block I do:
objectA = nil;
I get the compiler slackening by saying that it is trapping itself in this block and that will result in loops being saved. What for? I don't see myself here.
Then if I do:
self.objectB = nil;
No warnings! Anyway, I should expect a warning here.
Also, if:
[self methodA];
I am getting military affairs here. So I'm not really sure what's going on behind the scenes. I would have expected the first one to give me no warnings, and the last 2 to give me a warning (since I am holding a strong pointer to myself), but this is actually the opposite.
Here's an example:
@interface ListVC () {
NSObject *objectA;
}
@property (nonatomic, strong) NSObject *objectB;
- (void)methodA;
@end
and in viewDidLoad:
- (void)viewDidLoad {
[super viewDidLoad];
[self.tableView addPullToRefreshWithActionHandler:^{
self.objectB = nil; //no warning here
objectA = nil; //warning here
[self methodA]; //warning here (if i place this above previous warning
}];
}
source to share
It seems to me that the compiler just doesn't stop you from warning you about the same block several times. I'm not sure what counts as a function, but I don't see what else might be happening.
Assuming we are using the exact same compiler version (my Apple LLVM 4.2) try this:
@interface Jubilee : NSObject
@property (copy, nonatomic) NSData * d;
@end
@implementation Jubilee
{
NSString * s;
dispatch_block_t block;
}
@synthesize d;
- (void)erase
{
block = ^{
s = @"Agamemnon";
};
block = ^{
self.d = [NSData data];
};
block = ^{
[self prevaricate];
};
}
- (void)assemble
{
block = ^{
s = @"Agamemnon";
self.d = [NSData data];
[self prevaricate];
};
}
- (void)prevaricate
{
}
@end
I get a warning on every block inside erase
, but only for the first line of the block in assemble
. The warning will be correct on any of these lines. When you reference the ivar, it is implicit self->ivar;
and the block will store self
, not the object in the ivar.
source to share