0
votes

Let's say in iOS we have:

In W2AppDelegate.m:

GlobalViewController *globalVc;

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
...

}

In SomeOtherViewController.m:

- (void)viewDidLoad {
    [super viewDidLoad];

    [globalVc doSomething^{
       [globalVc.someVariable doSomethingElse]; // Is there a retain cycle here?
    }];
}

Is there a retain cycle here since we have a strong reference to globalVc inside the block.

globalVc -> block -> globalVc

3
I think everybody below is saying that this: "globalVc -> block -> globalVc" is a cycle, but that depends on: "globalVc -> block" being true in your code, which is unclear from the question.danh

3 Answers

3
votes

Is there a retain cycle here since we have a strong reference to globalVc inside the block.

No. Because Blocks capture local variables only.

[globalVc doSomething^{
   [globalVc.someVariable doSomethingElse]; // Is there a retain cycle here?
}];

globalVc wasn't captured by the block because globalVc is global variable. No local variables here, So the block doesn't capture any objects, Thus the block doesn't retain any objects at all.

1
votes

You have defined your globalVc variable as a global variable in your app delegate. An When you create a GlobalViewController it will persist for the life of you application. Sometimes you want a view controller to persist forever.

That's not a retain cycle, but it does tie up memory for the life of your app.

If you are only using it for doing tasks like executing blocks, and never display it's content view to the screen, you should probably make the class something other than a view controller.

I will sometimes create a Utils singleton that I use to provide app-wide utility functions. I write an accessor function like

+(Utils *) sharedUtils;

That returns a pointer to the Utils singleton. That's cleaner than using a global like you're doing.

1
votes

Ignoring the bad design - it depends.

If you store a block in an ivar and that block references the object that the ivar is on then you will indeed get a retain cycle - see below:

enter image description here

If you do not actually store the block but you are instead just invoking the block then you'll end up with the possibility that no additional retain is taken at all - see below

enter image description here


It's not clear if your GlobalViewController is a singleton or just a global reference that can be updated. If it's a singleton then retain cycles are less of a concern as you expect the object to live for the life of the program anyway.