我正在实现一个单例类,如下所示:
static Singleton* _singletonInstance;
@implementation Singleton
+(void)initialize
{
_singletonInstance = [[Singleton alloc] init];
}
+(Singleton*)instance
{
return(_singletonInstance);
}
初始化只在第一次有人调用实例时调用。然后我有一个方法,我可以调用它来设置一些实例变量。所以最终看起来像这样。
_singleton = [Singleton instance];
[_singleton setupWithParams: blah];
当我在对象中获得这个单例的实例时,它第一次正常工作;但是,在我dealloc并创建需要单例实例的对象的新副本后,当我尝试调用setup函数时,我得到一个BAD ACCESS错误。
只是为了测试我在进行设置调用之前打印出实例的地址,并且两次都报告相同的地址,但是当我检查错误日志中的BAD ACCESS调用时,它会列出一个完全不同的内存地址。
当我打印它时,有没有人知道为什么这个指向实例的指针看起来很好,但是当我调用它时,它似乎指向随机数据?
答案 0 :(得分:3)
指针值看起来有效,因为它曾经是,但很可能是内存已被释放,这就是为什么它指向看起来像随机数据。
您已经使用上面的[[Singleton alloc] init]
获得了一个引用,但是其他地方是否有release
可能正在执行?我打赌你的代码正在调用instance
,然后调用release
- 稍后,即使你的代码从未获得引用。对于单身人士来说,这不应该是必要的。只是一个猜测...
答案 1 :(得分:1)
您是否在某处释放了_singletonInstance?
答案 2 :(得分:1)
我使用的是更复杂但非常稳定的Singleton模板版本(使用Brandon "Quazie" Kwaselow Blog中的描述):
static SampleSingleton *sharedSampleSingletonDelegate = nil;
+ (SampleSingleton *)sharedInstance {
@synchronized(self) {
if (sharedSampleSingletonDelegate == nil) {
[[self alloc] init]; // assignment not done here
}
}
return sharedSampleSingletonDelegate;
}
+ (id)allocWithZone:(NSZone *)zone {
@synchronized(self) {
if (sharedSampleSingletonDelegate == nil) {
sharedSampleSingletonDelegate = [super allocWithZone:zone];
// assignment and return on first allocation
return sharedSampleSingletonDelegate;
}
}
// on subsequent allocation attempts return nil
return nil;
}
- (id)copyWithZone:(NSZone *)zone
{
return self;
}
- (id)retain {
return self;
}
- (unsigned)retainCount {
return UINT_MAX; // denotes an object that cannot be released
}
- (void)release {
//do nothing
}
- (id)autorelease {
return self;
}
答案 3 :(得分:1)
Valerii的代码更适合实现单例,但几乎可以肯定的是,调用[Singleton实例]的代码运行就好像它拥有所有权而没有实际使用retain获取所有权,然后才释放它。
查找您的错误,并阅读Memory Managment Rules。
此外,在Xcode中,enable NSZombieEnabled和控制台会在您尝试在对象发布后向其发送消息时显示。