【问题标题】:NSBlockOperation and objects in the blockNSBlockOperation 和块中的对象
【发布时间】:2014-06-25 19:44:51
【问题描述】:

下面是简单的代码:

// let's assume that I have to allocate this variable with alloc/init
NSString *someString = [[NSString alloc] initWithFormat:"%@", @"someString"];

NSBlockOperation *op = [NSBlockOperation blockOperationWithBlock:^{
  [someClass someFunction: someString];
}];

[queue addOperation:op]

[someString release];

由于 someString 被释放,当运行 nsblockoperation 时,此代码将崩溃。 防止这种情况的最佳做法是什么?

谢谢。

编辑:ARC 不是一个选择,因为这不是我的决定。有什么办法可以在 MRC 中解决这个问题?

EDIT2:下面的代码呢?行得通吗?

// let's assume that I have to allocate this variable with alloc/init
NSString *someString = [[NSString alloc] initWithFormat:"%@", @"someString"];

[someString retain]
NSBlockOperation *op = [NSBlockOperation blockOperationWithBlock:^{
  [someClass someFunction: someString];
  [someString release]
}];

[queue addOperation:op]

[someString release];

【问题讨论】:

  • 你到底为什么不使用 ARC?
  • 如果这不是你的决定,那就拿起一把锤子,尽可能地用力敲打想要使用 MMR 的人的头部。
  • 感谢您的建议。不幸的是,这也不是一个选择。还有其他选择吗??
  • 可以在文件级别关闭/打开 ARC。也许在这种情况下使用 ARC。它会让你头疼。也就是说,如果该操作从未执行(例如:被取消),您可能会在这里发生泄漏。此外,在分配后无需添加额外的保留 - 只需省略它和释放(在 addOperation 之后)。但是,如果操作被取消,则没有简单的方法来解决释放字符串的情况。您可能最好创建自己的 NSOperation 类,该类保留字符串并在操作被释放时释放它。

标签: ios nsoperation nsblockoperation


【解决方案1】:
// let's say the variable is allocated with alloc/init
NSString *someString = [[[NSString alloc] initWithFormat:"%@", @"someString"] autorelease];

NSBlockOperation *op = [NSBlockOperation blockOperationWithBlock:^{
  [someClass someFunction: someString];
}];

[queue addOperation:op];

周围有成千上万的应用需要维护并且不使用 ARC。将字符串包装在自动释放中。我认为这应该可行,但我没有测试。

【讨论】:

    【解决方案2】:

    你真的应该使用自动引用计数,并将代码简化为

    // let's say the variable is allocated with alloc/init
    NSString *someString = @"someString";
    
    NSBlockOperation *op = [NSBlockOperation blockOperationWithBlock:^{
      [someClass someFunction: someString];
    }];
    
    [queue addOperation:op]
    

    如果你真的必须使用手动引用计数,你可以这样做:

    // let's assume that I have to allocate this variable with alloc/init
    NSString *someString = [[NSString alloc] initWithFormat:"%@", @"someString"];
    
    NSBlockOperation *op = [NSBlockOperation blockOperationWithBlock:^{
      [someClass someFunction: someString];
      [someString release]
    }];
    
    [queue addOperation:op]
    

    我知道它只是示例代码,但如果不是,您也可以这样做... ;)

    NSBlockOperation *op = [NSBlockOperation blockOperationWithBlock:^{
      [someClass someFunction:@"someString"];
    }];
    
    [queue addOperation:op]
    

    【讨论】:

    • 感谢您的建议。但是,ARC 不是我的选择。 MRC 有什么解决方法吗?我还编辑了我的 OP。抱歉没有提。
    • @user3776727 嗯,也许你提供一些真实的代码?在您发布的代码中,您只需将someString 替换为@"someString" 并将变量someString 完全转储到块之外,包括-release
    • @user3776727 此外,[[NSString alloc] initWithFormat:"%@", "someString"] 会崩溃,因为您在"someString" 前面缺少@(我怀疑“some”转换为正确的32 位-isa -指针...)
    • 我也做不到。我无法从我发布的代码中更改两件事。 1. ARC -> MRC 2. 创建变量时使用 alloc/init。鉴于此,我猜没有办法解决这个问题??
    • 我修复了关于 @"someString" 的 OP。感谢您指出这一点。
    猜你喜欢
    • 2014-10-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-02-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-17
    相关资源
    最近更新 更多