Member of singleton class being released somehow?
Here's my Singleton Object.
#import "SettingsManager.h"
//#import "SynthesizeSingleton.h"
@implementation SettingsManager
//SYNTHESIZE_SINGLETON_FOR_CLASS(SettingsManager);
static SettingsManager* _sharedSettingsManager =nil;
-(NSString *)getString:(NSString*)value
{
return [settings objectForKey:value];
}
-(NSMutableDictionary*)getSettingsArray
{
return settings;
}
-(int)getInt:(NSString*)value {
return [[settings objectForKey:value] intValue];
}
-(void)setValue:(NSString*)value newString:(NSString *)aValue {
[settings setObject:aValue forKey:value];
}
-(void)setValue:(NSString*)value newInt:(int)aValue {
[setti开发者_运维百科ngs setObject:[NSString stringWithFormat:@"%i",aValue] forKey:value];
}
-(void)save
{
[[NSUserDefaults standardUserDefaults] setObject:settings forKey:@"ClimbingStrategy"];
[[NSUserDefaults standardUserDefaults] synchronize];
}
-(void)load
{
[settings addEntriesFromDictionary:[[NSUserDefaults standardUserDefaults] objectForKey:@"ClimbingStrategy"]];
}
-(void)logSettings
{
for(NSString* item in [settings allKeys])
{
NSLog(@"[SettingsManager KEY:%@ - VALUE:%@]", item, [settings valueForKey:item]);
}
}
+(SettingsManager*)sharedSettingsManager
{
if(!_sharedSettingsManager)
{
_sharedSettingsManager = [[super allocWithZone:NULL] init];
}
return _sharedSettingsManager;
}
+ (id)allocWithZone:(NSZone *)zone
{
return [[self sharedSettingsManager] retain];
}
- (id)copyWithZone:(NSZone *)zone
{
return self;
}
- (id)retain
{
return self;
}
- (NSUInteger)retainCount
{
return NSUIntegerMax; //denotes an object that cannot be released
}
- (void)release
{
//do nothing
}
- (id)autorelease
{
return self;
}
-(id)init {
settings = [[NSMutableDictionary alloc] initWithCapacity:10];
return [super init];
}
@end
Where settings is an NSMutableDictionary. After 4 or 5 access to the singleton object, the singleton object releases the "settings" dictionary. I can't find out where I programmed this wrong. I've tried stepping through it but I never found the exact place of when the settings object magically vanishes.
update i've updated the code, copied straight from apple's website. I've also used the macro for the singleton. both are still having problems with the settings nsmutabledictionary.
Update2: I'm getting this when I try to access the settings array:
Program received signal EXC_BAD_ACCESS, Could not access memory. Reason: KERN_INVALID_ADDRESS at address: 0x59200000 0x0177d09f in objc_msgSend () The program being debugged was signaled while in a function called from GDB. GDB has restored the context to what it was before the call. To change this behavior use "set unwindonsignal off" Evaluation of the expression containing the function (_NSPrintForDebugger) will be abandoned.
Singletons in Objective-C usually override release
to prevent this happening. See the sample code in the Cocoa Fundamentals Guide.
Set a watchpoint on the settings variable in your debugger...
watch settings == nil
and it will stop when/where the variable is released.
Matt Gallager has a drop-in macro based on Apple's code that makes it very simple to implement a singleton. There's a link to the code about half way down the page under the "Singletons in Cocoa" section:
http://cocoawithlove.com/2008/11/singletons-appdelegates-and-top-level.html
Where do you call [[SettingsManager sharedSettingsManager] settings]
?
What do you do with the returned object?
Do you possibly have something like the following?
NSMutableDictionary *s = [[SettingsManager sharedSettingsManager] settings];
⋮
[s release];
If this is the case, then you should take care to either first send -retain
to the object (after getting it from -settings
), or refrain from sending -release
. Or, you may want to rewrite -settings
so that it returns an autoreleased copy of the dictionary instead of the dictionary itself (to prevent callers from modifying it from “underneath” you).
You may want to review the Memory Management Programming Guide and its Object Ownership and Disposal, and Accessor Methods sections.
Nevermind guys. I found the error. It turns out when you overrelease an object within the NSMutableDictionary (the settings object) (which I thought I copied that specific object to another object, but it turned out to be a pointer to the object within the NSMutableDictionary), the settings object releases itself as well? The entire NSMutableDictionary became inaccessible. man that's impossible to debug!
精彩评论