In my project I've AuxState.h where I define
extern NSString *kStrAgentStateLogin;
extern NSString *kStrAgentStateAvailable;
extern NSString *kStrAgentStateLogOff;
extern NSString *kStrAgentStateLunch;
extern NSString *kStrUnavailable_IDLE;
In AuxState.m I have
NSString *kStrAgentStateLogin;
NSString *kStrA开发者_开发技巧gentStateAvailable;
NSString *kStrAgentStateLunch;
NSString *kStrAgentStateLogOff;
NSString *kStrUnavailable_IDLE;
In my Appdelegate.m I've imported AuxState.h and have defined the following method which sets the extern variables
-(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";
}
}
Now the Values read in are same in both the cases. I checked them by doing NSLog also. So no problem in reading from the plist.
If I am using the 2nd part, result is as expected and extern is recognized everywhere. :)
If I am using the 1st part the problem is that I receive "EXC_BAD_ACCESS" :( wherever I am accessing these extern values and if I place my mouse over the variables in debugging mode I can see that it prints "out of scope" but Extern variables have scope throughout the entire code. Whats the mystery. Anyone???
If you're not running under garbage collection, then the 1st part code needs to be retaining those strings. Otherwise they're liable to be deallocated shortly after you assign them, and you'll be left with pointers to deallocated objects. That's a great way to get EXC_BAD_ACCESS crashes.
Although those extern
variables do have the same lifetime as the program, that’s not necessarily true of the objects they point to:
kStrAgentStateLogin = @"ログイン";
The rvalue is a literal (or constant) NSString
, which is never deallocated by the runtime so you don’t have to worry about memory management of that string.
kStrAgentStateLogin=[[[NSDictionary dictionaryWithContentsOfFile:[[NSBundle mainBundle] pathForResource:kAuxStatesDictFile ofType:@"plist"]] allKeysForObject:kStrAgentStateLogin] objectAtIndex:0];
The rvalue is a string you do not own (i.e., you haven’t obtained it via a NARC method — new, alloc, retain, copy) so you cannot expect it to live throughout the execution of your program. You should use -retain
to own that string, making it sure it will be valid throughout your program.
精彩评论