Search code examples
iosobjective-cobjective-c-blocksretain-cycle

How is a property related to "self" and vice-versa?


My question is two-part:

First, Say I have a class:

MyClass.h

@interface MyClass: NSObject

-(id)initWithName:(NSString*)name;

@property(nonatomic, strong) NSString *name;

@end

MyClass.m

@implementation MyClass

-(id)initWithName:(NSString*)name
{
    if (self = [super init])
    {
        self.name = name;
    }
    return self;
}

@end

My question: I know that self will hold the name property strongly. But how will the name property relate to self? What I mean is that I can access name as self.name but while class instantiation, how is the children of self (which in this case is name) related to self? I am imagining the structure of the class as a tree, with the parent holding strong reference to the children and the children holding a weak reference to the parent. I want to know if I am thinking about it correctly or not. My guess is it will be a weak relationship.

Second, if I add a method which has a block that references the name property. So my updated implementation of MyClass.m is:

MyClass.m

@implementation MyClass

-(id)initWithName:(NSString*)name
{
    if (self = [super init])
    {
        self.name = name;
    }
    return self;
}

-(void)doSomeStuff
{
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        self.name = @"Name changed inside block";
}];
}

@end

My second question is: I am not referencing self directly inside my block. So, I guess there is no retain cycle here. But I am referencing name property which is held by self. So does this create a retain cycle?


Solution

  • I know that self will hold the name property strongly. But how will the name property relate to self?

    Each property will have a backing instance variable, conventionally named the same as the property with a leading underscore and a getter and/or setter method. There is no relationship; the property generally makes the class instance larger (due to additional instance variable) and the class larger (due to additional methods).

    I am not referencing self directly inside my block. So, I guess there is no retain cycle here. But I am referencing name property which is held by self. So does this create a retain cycle?

    Yes you are referencing self directly, so a retain cycle is possible. However a retain cycle can only happen under certain circumstances, and it's often just safer to avoid this by creating a weak reference to self and using that within the block.