What is equivalent to [[[save something] autorelease] in ARC?

What is equivalent to [[something retain] autorelease] in ARC?

I have a problem where the DBRequest class calls my delegate to signify completion. Then my delegate sets the instance of DBRequest to nil, which overrides it. But then when the stack pops up from my delegate and returns to DBRequest, it certainly fails.

If I hadn’t been in ARC, in my delegate I just did [[theDbRequest retain] autorelease] before releasing my link to it so that it would survive long enough until the next cycle of the cycle to auto-implement it.

What should I do in ARC?

+6
source share
3 answers

How about adding something like

 __strong DBRequest * myself = self; [delegate reportDone]; 

I think that it will increase the object itself to the end of the function, to prevent it from happening earlier.

+6
source

Then my delegate sets the instance of DBRequest to nil, which overrides it. But then when the stack pops up from my delegate and returns to DBRequest, it certainly fails.

Of course, that was always a bad strategy, and your [[theDbRequest retain] autorelease] always just hid the problem, right?

Just do nothing. This way your instance variable is stored around; So what? You know that ARC will release it for you when you are free.

It is important not to release theDbRequest , but to set the link to DbRequest for you (the delegate) to zero so that it does not try to call you back when you no longer exist. Your own dealloc would be a good place for this.

I hope I understand the problem correctly. If not, write some code!

+3
source

As @matt says that if you just do nothing, ARC should be cleared when your object is freed. The DBRequest assignment that you create for the instance variable is handled by the fact that (assuming, of course, your object is superior to the object you create).

If you need to free DBRequest before your object dies, you will need an ARC-compatible "trick" equivalent to [[theDbRequest retain] autorelease] . Now, if you do not create your own auto-join pools, your previous approach will fire at the end of the current event. Following this logic, try:

  • Add a method to your class that simply sets theDbRequest to nil , name it cleanUpTheDbRequest .
  • Change the delegate callback to call [self performSelectorOnMainThread:@selector(cleanUpTheDbRequest) withObject:nil waitUntilDone:NO] instead of directly assigning nil to theDbRequest

This should delay assignment of nil until the end of the current event, just as your “automaton” did. It also works if your DBRequest lives in several events - the previous method fires at the end of the event that autorelease is called autorelease , this method calls the delegate method at the end of the event.

+3
source

Source: https://habr.com/ru/post/910390/


All Articles