NSBlockOperation 和块中的对象

Posted

技术标签:

【中文标题】NSBlockOperation 和块中的对象【英文标题】:NSBlockOperation and objects in the block 【发布时间】: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 类,该类保留字符串并在操作被释放时释放它。 【参考方案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。感谢您指出这一点。

以上是关于NSBlockOperation 和块中的对象的主要内容,如果未能解决你的问题,请参考以下文章

在块中修改后未更新 Swift 结构

Postgresql物理存储结构

从 NSBlockOperation 获得价值?

NSBlockOperation 的粒度状态

解析 NSBlockOperation 的 executionBlocks

带有嵌套完成块的 NSBlockOperation