多线程和自动释放池

发布于 2024-10-16 23:13:05 字数 516 浏览 3 评论 0原文

当我通过 GCD 掌握多线程技能时,我遇到了一些问题。假设您有以下方法:

    - (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?
    });
}

我想知道这是否正确,因为我认为我应该在块执行之前保留字符串:事实上,我担心事件循环完成并发送 string 一个自动释放在块中使用 string 之前的消息。那会使程序崩溃。

我说得对吗?我应该向 string 发送保留和释放消息还是这是正确的实现? 提前致谢!

As I'm mastering my skills with multithreading with GCD, I've come 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'm wondering if this is correct, because I think I should have retained string before the block execution: in fact I fear that the event loop finishes and sends string an autorelease message before using string in the block. That would crash the program.

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

病女 2024-10-23 23:13:05

我想知道这是否正确,因为我认为我应该在块执行之前保留字符串:事实上,我担心事件循环完成并在块中使用字符串之前向字符串发送自动释放消息。

不要害怕:
块捕获周围方法/函数的范围,因为它自动保留在块内部使用的任何对象变量。请注意,当您在块内使用 self 时,因为这可能会极大地影响对象的生命周期!

此规则有一个例外,那就是声明为

__block SomeObjectPointerType variableName

Update 的

变量。因为对此答案有一个新注释,我可能应该补充一点,随着 ARC 的引入,情况发生了一些变化:

在 ARC 下,所有对象变量默认为 __strong,并且这也适用于用__block标记的变量。如果你想避免强捕获块中的变量,你应该定义一个局部变量__weak

结束更新

如果您想了解有关块的更多信息,bbum 举办了一场精彩的会议,名为介绍块和Grand Central Dispatch 在 WWDC 2010 上的 iPhone 上

“区块详细信息”部分于 11:30 开始。

I'm wondering if this is correct, because I think I should have retained string before the block execution: in fact I fear that the event loop finishes and sends string an autorelease message before using string in the block.

Fear not:
A block captures the scope of the surrounding method/function in that it automatically retains any object-variable that is used inside of the block. Be aware of that when you use self inside of a block, as this may greatly affect the lifetime of the object!

There is one exception to this rule, and that are variables declared as

__block SomeObjectPointerType variableName

Update

Because there’s a new comment on this answer, I should probably add that things changed a little with the introduction of ARC:

Under ARC all object variables default to __strong, and this holds for variables marked with __block as well. If you want to avoid strong capturing of a variable in a block, you should define a local variable that is __weak.

End Update

If you like to learn more about blocks, bbum gave an excellent session called Introducing Blocks and Grand Central Dispatch on iPhone at WWDC 2010.

The "Block Details" section starts at 11:30.

荒人说梦 2024-10-23 23:13:05

令人担忧的是;自动释放对象何时释放?

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

myString 依赖于 stringVariable,每当 stringVariable 释放时,myString 就会立即释放。

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

在实践中,观察到 myString 可能会在该方法完成后立即释放。

现在,如果您更改代码并使用 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?
    });
}

自动释放对象在自动释放池释放它们所在的位置或它们所依赖的对象释放时释放。

现在,如果您在线程中使用该方法时,您应该在其中使用自动释放池。

- (void)method {
    NSAutoreleasePool pool = [[NSAutoreleasePool alloc] init];

        // lengthy operations ...
    [pool release];
}

The concern is; when an autorelease object releases?

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

The myString depends upon stringVariable, whenever stringVariable releases the myString immediately releases.

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

In practice it is observed the myString might be releases just after the completion of the method.

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?
    });
}

The autorelease objects released when the auto release pool releases in which they exists or when the object releases on which they depends.

Now if you are using the method in a thread you should use auto release pool inside it.

- (void)method {
    NSAutoreleasePool pool = [[NSAutoreleasePool alloc] init];

        // lengthy operations ...
    [pool release];
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文