Bogdan Balta Bogdan Balta - 5 months ago 56
iOS Question

Does a singleton create retain cycle inside block?

I have a singleton and I want to capture it inside a block. I know that variables are retained inside a block because a constant copy of the objects passed is created and never deallocated unless using a weak instance of that object. The curiosity I have is whether the same behaviour is applied to a statically allocated variable.
Here is my code (self is the sharedInstance of Class):

+ (Class *)sharedInstance
{
static Class *sharedInstance = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sharedInstance = [[Class alloc] init];
});
return sharedInstance;
}

[self setBlock:^(NSArray *array)
{
self.property = [array firstObject];
}];

Answer

Your claim that “a constant copy of the objects passed is created” is incorrect. The block creates __strong or __weak or __unsafe_unretained references to the objects that it uses; it doesn't copy the objects.

Your code creates a retain cycle between self and the block object, because the block has a strong reference to self and (assuming self.property is strong) self has a strong reference to the block.

The compiler doesn't understand the concept of a singleton. It doesn't know there's anything special about the lifetime of sharedInstance. So it doesn't do anything different with the block just because you've set up self as a singleton.