JLT JLT - 4 months ago 12
iOS Question

Declaring a Block In a Super Class That Can Be Accessed By Subclasses

I have a BaseViewController which contains a property of type block:

typedef void (^result)(BOOL didSend);

@class ShakeView;

@interface BaseViewController : UIViewController

@property result mPlayerControlResultHandler;

@end


I want that this block can be accessible by other subclasses. So in
viewDidLoad
of BaseViewController I did this to initialise the block:

- (void)viewDidLoad
{
[super viewDidLoad];

_mPlayerControlResultHandler = ^(BOOL didSend)
{
if(!didSend)
{
__block BaseViewController *blocksafeSelf = self;

[blocksafeSelf onOperatingSpeakerShortConnectionFailure];
}
};
}


This would throw a warning


Capturing self strongly in this block is likely to lead a retain cycle


So I searched for a solution this and tried everything suggested here but still unable to solve the problem.

Answer

Since the BaseViewController retains the block, and the block retains the objects it references, referring to self in the block causes a retain cycle.

The block doesn't modify the value of self, so it needn't be qualified with __block. Instead, it should be declared weak and moved outside of the block:

__weak BaseViewController *blocksafeSelf = self;

_mPlayerControlResultHandler = ^(BOOL didSend)
{
    if(!didSend)
    {
        [blocksafeSelf onOperatingSpeakerShortConnectionFailure];
    }
};