0

In my view-controller usually I load some data from server and call some function to render data or do some action when request data comes back from server. following is the snippet of such code.

- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
    __weak typeof(self) weakSelf = self;
    [MyRequestManager loadObjects: ^(MyObject* object, NSError* error) {
        weakSelf.textField.text = object.text;
        //do some other actions
    }];
}

If before data comes from server view is disappeared/unloaded, will callback will be called? If it is called there are chances of crash of unexpected things to happen. So how can we prevent that from happening?

I can think of one way to set a variable in viewWillAppear and viewWillDisappear. What is recommended way of doing this?

hridayesh
  • 1,123
  • 1
  • 14
  • 36

1 Answers1

1

As you're keeping weakself inside, self won't be retained, so it will be dealloced. You should make your weakself a strong value inside, use the strong one and it won't crash.

__weak typeof(self) weakSelf = self;
dispatch_group_async(_operationsGroup, _operationsQueue, ^{
    typeof(self) strongSelf = weakSelf;
    if (strongSelf) {
        [strongSelf doSomething];
        [strongSelf doSomethingElse];
    }
});

You may find more depth information eg here: http://albertodebortoli.github.io/blog/2013/08/03/objective-c-blocks-caveat/

Nat
  • 12,032
  • 9
  • 56
  • 103
  • is it correct to initialize weakSelf outside block, then make strong reference when callback is actually called? I dont want my callback to be called when view is disappeared. – hridayesh Jul 17 '15 at 08:13
  • @hridayesh Yes, think this way: when you're keeping block in memory (but not using it yet, method inside isn't called yet) you don't have strong reference so it will be dealloced in case it needs. When you start to perform the block, you make it strong (and check if it exists) so it won't disappear when you do your stuff. After performing block, the block will be dealloced, as well as everything inside, so retain count of self will also drop. If your real view got released from main thread in the meantime, it will be dealloced because block also doesn't exists already. – Nat Jul 17 '15 at 08:17
  • @hridayesh You can look in these refs to get more info: http://stackoverflow.com/a/17105368/849616, http://albertodebortoli.github.io/blog/2013/08/03/objective-c-blocks-caveat/ etc. Many refs to follow here. – Nat Jul 17 '15 at 08:19
  • Thanks for clarification Vive. What happens if this view is a page of page view controller. when going to different page, will current page be deallocated as well or just disappeared. In any case I dont want callback function to be called. – hridayesh Jul 17 '15 at 08:20
  • @hridayesh You may refer to this: http://stackoverflow.com/questions/15832644/unloading-viewcontrollers-from-uipageviewcontroller. PageViewController keeps previous & next page in the memory as far as I remember, so it may call your function. What's happening in block that you don't want it to be called so badly? – Nat Jul 17 '15 at 08:30
  • Thanks Vive. It was very helpful in understanding the concept! You may consider editting answer to include links. – hridayesh Jul 17 '15 at 08:31