Gikas Gikas - 1 month ago 19
Objective-C Question

Will there be retain cycle?

Here is some abstract code. There is base class "BaseClass" and child class "MyClass"

BaseClass

@property (nonatomic, copy) BlockType block;

- initBaseClassWithBlock:(BlockType)block {
self = [super init];

if (self) {
self.block = block;
}

return self;
}

MYClass : BaseClass

@property (strong, nonatomic) NSString *myString;

- (instancetype)init {
self = [super initBaseClassWithBlock:^{
NSLog(@"%@", self.myString);
}

return self;
}


Will there be retain cycle in MyClass init method?

Answer

Yes; that is a retain cycle.

You can check by pasting the code into a simple project and then using Xcode 8's memory graph debugger.

Copy/paste this compilable version of your code then build and run. It'll run forever and do nothing. Click the little object graph debugger icon (the three circles with lines in them) and it'll show you that you have a strong reference from the instance of sub back to itself via the block.

@interface Base:NSObject
@property (nonatomic, copy) dispatch_block_t block;
@end
@interface Sub:Base
@property (strong, nonatomic) NSString *myString;
@end

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        Sub *s = [[Sub alloc] init];
    }
    dispatch_main();
    return 0;
}

@implementation Base
- initBaseClassWithBlock:(dispatch_block_t)block
{
    self = [super init];

    if (self) {
        self.block = block;
    }

    return self;
}
@end


@implementation Sub
- (instancetype)init {
    if (self = [super initBaseClassWithBlock:^{
        NSLog(@"%@", self.myString);
    }]) {
        ;
    }
    return self;
}
@end