I have an Objective-C object where I'm passing a Block to it's constructor. It's a special case where I want to fire that Block in a view controller when it loads completely. However, in that Block I also want to reference the object that I'm passing the Block into. Consider this example:
typedef void (^MyBlock)();
//constructor of my object
-(id)initMyObjectWithBlock:(MyBlock)block{
self = [super init];
if(self){
myivar = block; //to be used later
}
}
//somewhere else in my app
MyObject *obj = [[MyObject alloc] initMyObjectWithBlock:^{
[obj doSomething];
}];
At that [obj doSomething]
line, I am getting "Variable is uninitialized when captured by block" warning, which makes sense. In that Block, I need a reference to the "parent" object (obj
in this case). Is there any way to achieve this? I do know workarounds and patterns to my specific problem, but I wanted to know if such a reference is possible.
If you simply set your object to nil
before creating an instance as following, it should take care of your warning.
__block TestClass *obj = nil;
obj = [[TestClass alloc] initMyObjectWithBlock:^{
[obj doSomething];
}];
Regarding object, it does exit since you are not calling block inside your initMyObjectWithBlock
initializer.
Although above code works, but as Josh mentioned, there is a retain cycle. To get around retain cycle, you can do something like:
TestClass *obj = nil;
__block __weak TestClass *objWeak = nil;
obj = [[TestClass alloc] initMyObjectWithBlock:^{
TestClass *newObj = objWeak;
[newObj doSomething];
}];
objWeak = obj;
Where you are simply creating a dummy variable to pass in to your block.