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 和块中的对象的主要内容,如果未能解决你的问题,请参考以下文章