Multithreaded and auto advertising

As I mastered my multithreading skills with GCD, I came across some question. Suppose you have the following method:

- (void)method { NSString *string= [NSString string]; //will be autoreleased dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ //very very lengthy operation... NSLog(@"%@", string); //is it safe? }); } 

I am wondering if this is correct, because I think I should have saved the string before the block was executed: in fact, I am afraid that the event loop will end and send a string about auto-detection before using string in the block, This will cause the program to crash.

I'm right? Should I send a save and release message to string or is this the correct implementation? Thanks in advance!

+5
source share
2 answers

I am wondering if this is correct, because I think I should have saved the line before the execution of the block: in fact, I am afraid that the event loop ends and sends the line an autorelease message before using the line in the block.

Do not be afraid:
The block captures the scope of the surrounding method / function in retain that it automatically retain any object variable that is used inside the block. Keep this in mind when you use self inside a block, as this can greatly affect the life of the object!

There is one exception to this rule: variables are declared as

 __block SomeObjectPointerType variableName 

Refresh

Since there is a new comment on this answer, I probably should add that with the advent of ARC, things have changed a bit:

In ARC, all object variables are set to __strong by default, and this applies to variables marked with __block . If you want to avoid the strong capture of a variable in a block, you must define a local variable __weak .

End of update

If you want to learn more about blocks, bbum had an excellent session entitled β€œ Presenting Blocks and Grand Central Dispatch on iPhone” at WWDC 2010.

The section "Information about the block" begins at 11:30.

+5
source

Troublesome; when is the release of an autoreference object?

 NSString *myString= [NSString stringWithFormat: @"%@", stringVariable]; 

myString is dependent on stringVariable, whenever stringVariable releases myString immediately releases.

 NSString *myString= [NSString stringWithString: @"stringVariable"]; 

In practice, it is observed that myString can be released immediately after the method completes.

Now, if you change your code and use NSAutoReleasePool

 - (void)method { NSAutoreleasePool pool = [[NSAutoreleasePool alloc] init]; NSString *string= [NSString string]; //will be autoreleased dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ //very very lengthy operation... // string will be released here [pool release]; NSLog(@"%@", string); // it is not safe? }); } 

Auto-advertising objects issued when the automatic release pool in which they exist or when the object is freed on which they depend.

Now, if you use a method in a stream, you must use the automatic release pool inside it.

 - (void)method { NSAutoreleasePool pool = [[NSAutoreleasePool alloc] init]; // lengthy operations ... [pool release]; } 
-5
source

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


All Articles