Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Block automatic retaining, does it affect even to ivars in self?

If I have class:

@interface A : NSObject
{
    BOOL b;
    id   c;
}
@end

and reference b and c in a block, is the block retain self automatically? Or just b and c? About c, it may be retained itself, but how about b?

like image 746
eonil Avatar asked Dec 27 '22 21:12

eonil


1 Answers

Bill's answer isn't quite correct:

If you have an instance of A and create a block inside of that instance like so:

^{
  b = YES;
}

Then self is retained (when the block is copied). b is not const-copied, because b is strongly referenced by self, and only self is const within the scope of the block.

On the other hand, if you do:

BOOL aBool = YES;
^{
  aBool = NO;
  c = [[NSObject alloc] init];
}

Then again, self is const-copied (and retained when the block itself is copied) and the assignment to c is allowed. However, the assignment to aBOOL is not allowed, because the value of aBool is const-copied.

In other words, the compiler recognizes the b and c are ivars, and will retain self instead of the ivars directly.


One way to think about this that helps me understand what's going on is to remember that an object is really just a fancy struct, which means you can technically access ivars via the arrow operator: ->

So when you're accessing ivars:

b = YES;

is equivalent to:

self->b = YES;

In that light, it makes perfect sense why you have to retain self, but b is not const. It's because b is only a slim part of the "bigger picture", and in order to get b, you must necessarily include all of self as well (since copying part of a struct doesn't really make sense in this context).

like image 72
Dave DeLong Avatar answered May 04 '23 00:05

Dave DeLong