【发布时间】:2014-01-29 17:05:24
【问题描述】:
环境:Mac OS X 10.9、Xcode 5.0.2
我正在为 OS X 创建标准 Cocoa 应用程序并在项目设置中禁用 ARC。添加一个按钮“运行”:
文件“AppDelegate.h”:
#import <Cocoa/Cocoa.h>
@interface AppDelegate : NSObject <NSApplicationDelegate>
@property (assign) IBOutlet NSWindow *window;
- (IBAction)clickRun:(id)sender;
@end
文件“AppDelegate.m”:
#import "AppDelegate.h"
@implementation AppDelegate
- (IBAction)clickRun:(id)sender
{
NSAutoreleasePool* apool = [[NSAutoreleasePool alloc] init];
NSString* pathToFile = @"/Users/admin/1.txt";
NSError* error;
NSLog(@"[1] Retain count of Error: %lx", [error retainCount]);
NSData* dataOfFile = [NSData dataWithContentsOfFile:pathToFile
options:NSDataReadingMappedIfSafe
error:&error];
NSLog(@"[2] Retain count of Error: %lx", [error retainCount]);
[apool drain];
}
@end
当运行程序和第一次点击按钮控制台有输出:
“[1] 保留错误计数:0”——当然为零,因为变量“错误”未初始化
"[2] Retain count of Error: 0" – 第二个零告诉我们什么方法“dataWithContentsOfFile”成功读取文件。
调试器总是说什么变量“error”的类型是“nil”。
但是当我第二次点击按钮时,调试器会中断:
NSLog(@"[1] Retain count of Error: %lx", [error retainCount]);
并显示消息“EXC_BAD_ACCESS”和变量“错误”包含垃圾,当然 [error retainCount] 就像分段错误一样。但这有点奇怪,因为如果方法“dataWithContentsOfFile”成功,它不会分配变量“错误”,也没有主体接触这个变量。
变量“error”从哪里获取垃圾,为什么第一次点击不包含垃圾?
当然花了几个小时后我解决了这个问题,强制(重新)初始化'nil':
NSError* error = nil;
但是上面的问题没有过期。
【问题讨论】:
-
那么你为什么忽略编译器关于未初始化变量的警告?
-
@Hot Licks 1 XCode 产生了很多警告,我已经被警告弄得眼花缭乱;)在 MS Visual Studio C++ 中,对我来说更整齐地推挤警告。 2 我在某处读到;)如果需要,dataWithContentsOfFile 会自动分配“错误”变量。但我不知道哪些指针类型的未初始化局部变量包含来自堆栈的垃圾。
-
作为一般规则,无论可能为 ARC 声明什么或其他什么,当您声明一个局部变量时,您应该在“读取”它之前显式地为其分配一个值。在创建它们时不初始化所有本地变量的唯一原因(除了很小的性能影响)是有时“未初始化变量”警告实际上有助于告诉您错过了什么。
-
我也混淆了调试器,它通过第一次单击(运行)显示变量“error”的类型为“nil”并包含 NSObject。我相信“nil”类型的含义不仅仅是归零。
标签: objective-c xcode memory initialization