Mat*_*man 13 objective-c llvm clang automatic-ref-counting
更新:这已在iOS 6.1 DP3 SDK中修复.
我使用默认版本构建配置使用ARC构建时,我已经跟踪了一个使用后释放崩溃(调试似乎工作正常).在具有非常量条件的if-scope中创建对象,将其分配给范围外部的变量,然后仅使用Objective-C数组或字典文字引用该变量时,会发生此问题.
这是我设法找到的最小的可重复的案例:
void test(BOOL arg)
{
id obj = nil;
if (arg) {
obj = [NSObject new];
}
// obj already deallocated here
@[obj];
// but using NSArray works
//[NSArray arrayWithObject:obj];
// @[obj] works if obj is referenced i.e. by NSLog print out
//NSLog(@"%@", obj);
}
int main(int argc, const char * argv[])
{
@autoreleasepool {
test(YES);
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
当我使用zombie对象构建并运行它时,我收到以下错误消息:
-[NSObject retain]: message sent to deallocated instance 0x100109100
Run Code Online (Sandbox Code Playgroud)
正如我在代码中评论的那样,如果obj
以其他方式引用它,它可以正常工作,例如使用NSLog
或使用NSArray
.我是否误解了如何使用ARC和作用域释放对象,或者这是LLVM或Clang中的优化错误?
我正在使用Xcode 4.5.2和clang 4.1版(标签/ Apple/clang-421.11.66)(基于LLVM 3.1svn).我可以在为iOS模拟器和Mac OS X构建x86 64位时重现它,我很确定在为ARM构建时出现同样的问题,因为在iPhone上运行发布版本时首次发现该问题.
我已向Apple提交了错误报告,并制作了一份开放式雷达报告.
什么,如果有的话,我错过了什么?
更新,做了一些实验:
正如Gabro指出编译器转换@[]
为[NSArray arrayWithObjects:count:]
语句所以我做了一些测试:
// works
id a[] = {obj};
[NSArray arrayWithObjects:a count:1];
// does not work
const id *b = (id[]){obj};
[NSArray arrayWithObjects:b count:1];
// does not work
[NSArray arrayWithObjects:(id[]){obj} count:1];
Run Code Online (Sandbox Code Playgroud)
所以我的猜测是,当组合ARC和匿名C数组时会发生这种情况.
我刚刚测试了针对 OSX (x86 64) 和 iOS Simulator 构建的以下代码,但无法重现该错误
void test(BOOL arg) {
id obj = nil;
if (arg) {
obj = [NSObject new];
}
@[obj];
NSLog(@"Hi there");
}
int main(int argc, const char * argv[]) {
@autoreleasepool {
test(YES);
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
上面的代码只是Hi there
在控制台中打印并返回。
我的配置与你的相同:XCode 4.5.2 和 Apple clang 版本 4.1 (tags/Apple/clang-421.11.66) (基于 LLVM 3.1svn) 作为编译器。
编辑
我还尝试使用命令行进行编译(#include <Foundation/Foundation.h>
在上面示例的开头添加之后)
clang -fobjc-arc -framework Foundation main.m
Run Code Online (Sandbox Code Playgroud)
结果又是
2012-12-03 12:47:45.647 a.out[39421:707] Hi there
Run Code Online (Sandbox Code Playgroud)
编辑2
正如评论中所指出的,可以重现增加优化级别的错误-O0
。总结:
clang -O0 -fobjc-arc -framework Foundation main.m
Run Code Online (Sandbox Code Playgroud)
该程序按预期运行
clang -O1 -fobjc-arc -framework Foundation main.m
Run Code Online (Sandbox Code Playgroud)
问题中提出的错误出现了。对于超过任何优化级别都是如此-O0
这绝对是编译器中的一个错误。
归档时间: |
|
查看次数: |
356 次 |
最近记录: |