Target save cycle creation (target C without GC)

Is there ever a case where intentionally creating a save cycle to prevent a release and then clean it up is the best solution?

If so, are there any examples of this under Cocoa Touch or NextStep?

I assume this question will be specific to Objective-C with ARC, since Objective-C with GC or other languages ​​with GC can behave differently.

+6
source share
2 answers

Sure. In fact, this is not so rare, although you cannot understand it.

For example, suppose my controller is making a network request, and I really need to make sure that I handle the response, even if the user has switched from that controller.

I could do something like this:

- (void)doNetworkThing { __block MyController *blockSelf = self; NSURLRequest *request = // some request [NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler: ^(NSURLResponse *response, NSData *data, NSError *error) { // Handle the response here [blockSelf doThingWithResponse:response]; }]; } 

This introduces a trivial save cycle in which self blockSelf itself to save by assigning itself to the strong blockSelf pointer. As long as blockSelf does not go beyond, I will not free myself.

Note that often you should use a weak pointer in this situation. But if you really need a controller to handle it, using a strong pointer also works. As soon as the handler block is freed, its link to blockSelf will disappear. Since the link to the blockSelf stack blockSelf also disappear, it will be freed if no one holds it.

Basically, blockSelf triggered a time save cycle, which was useful to ensure that the release could not happen until the request was complete. Since ARC automatically clears the hold counter when the __block variable goes out of scope, it is not very similar to a save loop. But nonetheless what it is.

+7
source

Of course, there are several. To the greatest extent, NSURLConnection generates a save loop with its delegate to ensure that the delegate cannot leave before the connection is completed. Somewhat less ideal, NSTimer creates a save loop with its purpose. This, unfortunately, causes problems for repeating timers (see RNTimer for one of many attempts to work around this problem).

Generally speaking, if a delegating object has a very short lifespan compared to its delegate, it is natural for him to save his delegate in order to create a useful save cycle.

This is much rarer, but still done, for certain types of objects that are "saved". For example, if you have an object that you want to create and perform some operation and then destroy yourself, then self-preservation can solve this problem. As a rule, it is better to avoid this and allow the caller to save the object, but he still uses it (I used it to register and other non-critical operations that I want to start and forget).

However, in my code it is often deliberate to create short-lived save cycles with blocks to ensure that the caller cannot disappear before the block completes.

+1
source

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


All Articles