在我的项目中,我 AuxState.h 我定义了
extern NSString *kStrAgentStateLogin;
extern NSString *kStrAgentStateAvailable;
extern NSString *kStrAgentStateLogOff;
extern NSString *kStrAgentStateLunch;
extern NSString *kStrUnavailable_IDLE;
在 AuxState.m 我有
NSString *kStrAgentStateLogin;
NSString *kStrAgentStateAvailable;
NSString *kStrAgentStateLunch;
NSString *kStrAgentStateLogOff;
NSString *kStrUnavailable_IDLE;
在我的 Appdelegate.m 中,我导入了 AuxState.h ,并定义了以下设置 extern 变量的方法
-(void) languageSetupForAuxStates
{
/* 1st Part */
kStrAgentStateLogin = @"Log In";
kStrAgentStateAvailable = @"Available";
kStrAgentStateLunch = @"Lunch";
kStrAgentStateLogOff = @"Log Off";
kStrUnavailable_IDLE = @"Unavailable/IDLE";
if([[[[NSUserDefaults standardUserDefaults] objectForKey:@"AppleLanguages"] objectAtIndex:0] isEqualToString:@"ja"]){
kStrAgentStateLogin=[[[NSDictionary dictionaryWithContentsOfFile:[[NSBundle mainBundle] pathForResource:kAuxStatesDictFile ofType:@"plist"]] allKeysForObject:kStrAgentStateLogin] objectAtIndex:0];
kStrAgentStateAvailable=[[[NSDictionary dictionaryWithContentsOfFile:[[NSBundle mainBundle] pathForResource:kAuxStatesDictFile ofType:@"plist"]] allKeysForObject:kStrAgentStateAvailable] objectAtIndex:0];
kStrAgentStateLunch=[[[NSDictionary dictionaryWithContentsOfFile:[[NSBundle mainBundle] pathForResource:kAuxStatesDictFile ofType:@"plist"]] allKeysForObject:kStrAgentStateLunch] objectAtIndex:0];
kStrUnavailable_IDLE=[[[NSDictionary dictionaryWithContentsOfFile:[[NSBundle mainBundle] pathForResource:kAuxStatesDictFile ofType:@"plist"]] allKeysForObject:kStrUnavailable_IDLE] objectAtIndex:0];
}
NSLog(@"kStrAgentStateLunch = %@",kStrAgentStateLunch);
/* 2nd Part */
if([[[[NSUserDefaults standardUserDefaults] objectForKey:@"AppleLanguages"] objectAtIndex:0] isEqualToString:@"ja"]){
NSLog(@"Agent language is Japan");
kStrAgentStateLogin = @"ログイン";
kStrAgentStateAvailable = @"利用可能";
kStrAgentStateLunch = @"昼食";
kStrAgentStateLogOff = @"ログオフ";
kStrUnavailable_IDLE = @"できない/アイドル";
}
else {
NSLog(@"Agent language is English");
kStrAgentStateLogin = @"Log In";
kStrAgentStateAvailable = @"Available";
kStrAgentStateLunch = @"Lunch";
kStrAgentStateLogOff = @"Log Off";
kStrUnavailable_IDLE = @"Unavailable/IDLE";
}
}
现在读取的值在两种情况下都是相同的。我也通过做NSLog来检查它们。所以从plist读取没有问题。
如果我使用第二部分,结果与预期一致,并且extern在任何地方都被识别。 :)
如果我正在使用第一部分,问题是我收到“EXC_BAD_ACCESS”:(无论我在哪里访问这些外部值,如果我将鼠标放在调试模式的变量上,我可以看到它打印“超出范围“但是外部变量在整个代码中都有范围。什么是神秘的。任何人???
答案 0 :(得分:2)
如果你没有在垃圾收集下运行,那么第一部分代码需要保留这些字符串。否则,在分配它们后不久它们就会被解除分配,并且你将留下指向解除分配对象的指针。这是让EXC_BAD_ACCESS崩溃的好方法。
答案 1 :(得分:2)
虽然这些extern
变量的确具有与程序相同的生命周期,但对于它们指向的对象并不一定如此:
kStrAgentStateLogin = @"ログイン";
rvalue是一个文字(或常量)NSString
,它永远不会被运行时解除分配,所以你不必担心该字符串的内存管理。
kStrAgentStateLogin=[[[NSDictionary dictionaryWithContentsOfFile:[[NSBundle mainBundle] pathForResource:kAuxStatesDictFile ofType:@"plist"]] allKeysForObject:kStrAgentStateLogin] objectAtIndex:0];
rvalue是一个你不拥有的字符串(即你没有通过NARC方法获得它 - new,alloc,retain,copy),所以你不能指望它在程序执行过程中存在。您应该使用-retain
拥有该字符串,确保它在整个程序中有效。