Singleton未正确初始化
我使用以下语句调用以下代码:SQLiteDB * db = [[[SQLiteDB alloc] init] autorelease];Singleton未正确初始化
问题是“sharedSQLiteDB”没有被调用,而是“allocWithZone”,因此“checkIfDatabaseExists”没有被调用,这是数据库创建的地方。
我不明白为什么...(即我究竟做错了什么?)
#import "SQLiteDB.h"
static SQLiteDB *sharedSQLiteDB = nil; // makes this a singleton class
@implementation SQLiteDB
@synthesize searchPaths, documentPath, databasePath, cDatabasePath;
#pragma mark Singleton Methods
+ (SQLiteDB *) sharedSQLiteDB {
if(!sharedSQLiteDB) {
sharedSQLiteDB = [[SQLiteDB alloc] init];
[sharedSQLiteDB checkIfDatabaseExists]; // check to see if d/b exists
}
return sharedSQLiteDB;
}
+(id)allocWithZone:(NSZone *)zone { // makes sure another instance is not allocated
if(!sharedSQLiteDB) {
sharedSQLiteDB = [super allocWithZone:zone];
return sharedSQLiteDB;
}
else {
return nil;
}
}
-(id)copyWithZone:(NSZone *)zone {
return self;
}
-(void) release {
// no-op
}
它不执行你的+ (SQLiteDB *) sharedSQLiteDB
方法,因为你没有实际调用该方法的任何地方。
正如您所见,当您拨打[[SQLiteDB alloc] init]
时,将调用allocWithZone
方法。
将您的呼叫改为SQLiteDB *db = [SQLiteDB sharedSQLiteDB]
,在这种情况下将调用您的checkIfDatabaseExists
方法。但是,如果[[SQLiteDB alloc] init]
在其他地方被调用,那么checkIfDatabaseExists
方法调用仍将被跳过。
也许考虑将checkIfDatabaseExists
方法转换为init
方法,以便它将用于您的单例方法和allocWithZone
。
老实说我没有看到任何错误... 但是我发布了我用来创建单例的代码。这是从一个来源,现在我不记得链接...这不是我的代码。
static DataManager *_instance;
@implementation DataManager
+ (DataManager*)sharedInstance
{
@synchronized(self) {
if (_instance == nil) {
_instance = [[super allocWithZone:NULL] init];
// Allocate/initialize any member variables of the singleton class her
// example
//_instance.member = @"";
}
}
return _instance;
}
#pragma mark Singleton Methods
+ (id)allocWithZone:(NSZone *)zone
{
return [[self sharedInstance]retain];
}
- (id)copyWithZone:(NSZone *)zone
{
return self;
}
- (id)retain
{
return self;
}
- (unsigned)retainCount
{
return NSUIntegerMax; //denotes an object that cannot be released
}
- (void)release
{
//do nothing
}
- (id)autorelease
{
return self;
}
我希望它能帮助
在Singleton模式的使用模式应该是:
SQLiteDB* db = [SQLiteDB sharedSQLiteDB];
他们的方式,你在呼唤它不适合singelton模式。所有的访问都应该通过你的sharedSQLiteDB消息。
换句话说,您不应该通过典型的Cocoa模式(SQLiteDB * db = [[[SQLiteDB alloc] init] autorelease];初始化;不正确并且存在问题)。
在使用默认的语言初始化模式(ObjC的alloc/init或C++的默认构造函数)的单例中,应该生成编译时错误消息,因为应该保护构造函数/ init方法。
查看Wikipedia条目。请参阅Design Pattern C++圣经。甚至有一个版本Cocoa
祝你好运。
我强烈建议使用由Matt Gallagher首先创建的SyntesizeSingleton头文件。
找到最新版本(我知道)在这里:
https://github.com/cjhanson/Objective-C-Optimized-Singleton
它使创建一个单独死的简单。
下面是一个例子标题:
#import <Foundation/Foundation.h>
@interface Example : NSObject {}
+(Example*)sharedExample;
@end
以及相应的.m:
#import "FMUser.h"
#import "SynthesizeSingleton.h"
@implementation Example
SYNTHESIZE_SINGLETON_FOR_CLASS(Example);
@end
[Example sharedExample]
为您创建。这很漂亮。
非常感谢......现在正在工作......我感谢大家的输入...... – SpokaneDude 2011-04-29 17:41:19