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
    }];
}

      

+3


source to share


2 answers


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.

+3


source


The first warning is correct. Access to an instance variable in a block will be implicitly persisted. The fact that you won't get a warning for the second statement almost seems like a compiler error.



+3


source







All Articles