NSMutableDictionary 单例问题
我正在使用 Cocos2D 框架编写 Objective-C 代码,并且我有一个用于多种用途的单例。一个新的目的是获取和设置字符的“状态”,即字符串。我最近为此目的制作了一个 NSDictionary,但是当调用单例中的方法时,我遇到了程序冻结的问题。
这是单例代码。我只是留下字符状态的东西:
.h
@interface ExGlobal : NSObject {
NSArray *charStates_keys;
NSArray *charStates_objects;
NSMutableDictionary *charStates;
}
@property(nonatomic, retain) NSMutableDictionary *charStates;
+(ExGlobal*)sharedSingleton;
- (NSString *)charState:(NSString *)charName;
- (void)set_charState:(NSString *)value forCharName:(NSString *)charName;
@end
.m
#import "ExGlobal.h"
@implementation ExGlobal
@synthesize charStates;
static ExGlobal* _sharedSingleton = nil;
+(ExGlobal*)sharedSingleton {
@synchronized([ExGlobal class]) {
if (!_sharedSingleton) {
[[self alloc] init];
}
return _sharedSingleton;
}
return nil;
}
+(id)alloc {
@synchronized([ExGlobal class]) {
NSAssert(_sharedSingleton == nil, @"Attempted to allocate a second instance of a singleton.");
_sharedSingleton = [super alloc];
return _sharedSingleton;
}
return nil;
}
-(id)init {
self = [super init];
if (self != nil) {
// initialize stuff here
exitName = @"ruinsSkyMid";
sceneChangeKind = @"reborn";
charStates = [[NSMutableDictionary alloc] init];
charStates_keys = [NSArray arrayWithObjects:@"Feathers", @"Hummus", nil];
charStates_objects = [NSArray arrayWithObjects:@"at wall", @"with Feathers", nil];
charStates = [NSMutableDictionary dictionaryWithObjects:charStates_objects forKeys:charStates_keys];
}
return self;
}
- (NSString *)charState:(NSString *)charName{
NSString *value = [charStates objectForKey:charName];
return value;
}
- (void)set_charState:(NSString *)charState forCharName:(NSString *)charName{
[charStates setObject:charState forKey:charName];
}
- (void)dealloc {
//I know it doesn't get called, but just in case
[charStates release];
[super dealloc];
}
@end
我不清楚它冻结时到底是什么问题。发生这种情况时,我在控制台中得到的只是:
Program received signal: “EXC_BAD_ACCESS”.
warning: Unable to read symbols for /Developer/Platforms/iPhoneOS.platform/DeviceSupport/4.3.5 (8L1)/Symbols/Developer/usr/lib/libXcodeDebuggerSupport.dylib (file not found).
Previous frame inner to this frame (gdb could not unwind past this frame)
Previous frame inner to this frame (gdb could not unwind past this frame)
我确信这无助于查找问题。我发现如果我在 charState 和 set_charState 方法中重新定义 charStates_keys、charStates_objects 和 charStates,它似乎可以在不冻结的情况下工作,但 set_charState 不会更改状态。
I am coding Objective-C using the Cocos2D framework, and I have a singleton used for multiple purposes. One new purposes is to get and set character's "states" which are strings. I've recently made an NSDictionary for this purpose, but I have issues with the program freezing up when a method inside the singleton is called.
Here's the singleton code. I'm just leaving in the character state stuff:
.h
@interface ExGlobal : NSObject {
NSArray *charStates_keys;
NSArray *charStates_objects;
NSMutableDictionary *charStates;
}
@property(nonatomic, retain) NSMutableDictionary *charStates;
+(ExGlobal*)sharedSingleton;
- (NSString *)charState:(NSString *)charName;
- (void)set_charState:(NSString *)value forCharName:(NSString *)charName;
@end
.m
#import "ExGlobal.h"
@implementation ExGlobal
@synthesize charStates;
static ExGlobal* _sharedSingleton = nil;
+(ExGlobal*)sharedSingleton {
@synchronized([ExGlobal class]) {
if (!_sharedSingleton) {
[[self alloc] init];
}
return _sharedSingleton;
}
return nil;
}
+(id)alloc {
@synchronized([ExGlobal class]) {
NSAssert(_sharedSingleton == nil, @"Attempted to allocate a second instance of a singleton.");
_sharedSingleton = [super alloc];
return _sharedSingleton;
}
return nil;
}
-(id)init {
self = [super init];
if (self != nil) {
// initialize stuff here
exitName = @"ruinsSkyMid";
sceneChangeKind = @"reborn";
charStates = [[NSMutableDictionary alloc] init];
charStates_keys = [NSArray arrayWithObjects:@"Feathers", @"Hummus", nil];
charStates_objects = [NSArray arrayWithObjects:@"at wall", @"with Feathers", nil];
charStates = [NSMutableDictionary dictionaryWithObjects:charStates_objects forKeys:charStates_keys];
}
return self;
}
- (NSString *)charState:(NSString *)charName{
NSString *value = [charStates objectForKey:charName];
return value;
}
- (void)set_charState:(NSString *)charState forCharName:(NSString *)charName{
[charStates setObject:charState forKey:charName];
}
- (void)dealloc {
//I know it doesn't get called, but just in case
[charStates release];
[super dealloc];
}
@end
It's unclear to me what exactly the issue is when it freezes. When this happens, all I get in the console is:
Program received signal: “EXC_BAD_ACCESS”.
warning: Unable to read symbols for /Developer/Platforms/iPhoneOS.platform/DeviceSupport/4.3.5 (8L1)/Symbols/Developer/usr/lib/libXcodeDebuggerSupport.dylib (file not found).
Previous frame inner to this frame (gdb could not unwind past this frame)
Previous frame inner to this frame (gdb could not unwind past this frame)
Which I'm sure doesn't help finding the issue. I found if I redefine charStates_keys, charStates_objects and charStates inside both the charState and set_charState methods, it seems to work without freezing, except set_charState does not change the state.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
不是冻结,而是崩溃。因此就有了
EXC_BAD_ACCESS
。看起来您的 Xcode 安装也已停止,因为不应出现以下两条消息。请注意,方法名称中不应包含
_
;不是问题的原因,而是对以下约定的评论。您没有保留 charStates,这可能是崩溃的原因。
It isn't freezing, it is crashing. Hence the
EXC_BAD_ACCESS
. It looks like your Xcode installation is borked, too, as the two messages following should not happen.Note that methods should not have
_
s in the name; not a cause of the problem, but a comment on following convention.You aren't retaining
charStates
and that is likely the cause of the crash.这不是一个答案,但我在上面的评论字段中没有足够的空间来发布此内容,但它可能有用。
正如 bbum 已经说过的,你缺乏保留 charStates 可能是问题所在。
如果您对何时保留和不保留对象感到困惑,有一本非常好的书,名为“在 Mac 上学习 Objective-C”,我知道这是一本 Mac 书,但其中大部分内容也适用于 iPhone。第 9 章(内存管理)第 171 页讨论了“内存管理规则”,以及如果您对何时保留或不保留感到困惑,那么您就不了解 Objective C 内存管理的简单规则。
本质上,如果您使用 new、alloc 或 copy 创建对象,则保留计数会自动设置为 1,因此该对象将被保留,并且不需要您保留它,并且需要后续释放才能取消分配。
如果您以任何其他方式创建对象,那么该对象将是自动释放的对象。
显然这些规则仅适用于标准 iOS 库,不一定适用于第三方库。
我建议任何不完全理解 Objective C 内存管理的人阅读这本书。我发现即使对于我的 iPhone 工作也很有启发。
希望有帮助/。
Not an answer as such but I didn't have enough space in the comments field above to post this, but it might be useful.
As bbum already said, your lack of retaining charStates is likely the problem.
If you are confused about when to retain and not retain objects there's a really good book called "Learn Objective-C on the Mac" and I know it's a Mac book but most of it applies to iPhone too. On page 171 of chapter 9 (Memory Management) it talks about the "Memory Management Rules" and how if you are confused about when to retain or not then you don't understand the simple rules of Objective C memory management.
Essentially if you create an object using new, alloc or copy, then the retain count is automatically set to 1 so the object is retained and does not require you to retain it and will require a subsequent release to deallocate.
If you create the object any other way then the object will be an autoreleased object.
Obviously these rules only apply within the standard iOS libraries and can't necessarily be applied to third party libraries.
I recommend anyone who doesn't fully understand memory management in Objective C read this book. I found highly enlightening even for my iPhone work.
Hope that helps/.