2011-04-29 152 views
0

我使用以下語句調用以下代碼: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 
} 

回答

0

它不執行你的+ (SQLiteDB *) sharedSQLiteDB方法,因爲你沒有實際調用該方法的任何地方。

正如您所見,當您撥打[[SQLiteDB alloc] init]時,將調用allocWithZone方法。

將您的呼叫改爲SQLiteDB *db = [SQLiteDB sharedSQLiteDB],在這種情況下將調用您的checkIfDatabaseExists方法。但是,如果[[SQLiteDB alloc] init]在其他地方被調用,那麼checkIfDatabaseExists方法調用仍將被跳過。

也許考慮將checkIfDatabaseExists方法轉換爲init方法,以便它將用於您的單例方法和allocWithZone

+0

非常感謝......現在正在工作......我感謝大家的輸入...... – SpokaneDude 2011-04-29 17:41:19

0

老實說我沒有看到任何錯誤... 但是我發佈了我用來創建單例的代碼。這是從一個來源,現在我不記得鏈接...這不是我的代碼。

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;  
} 

我希望它能幫助

1

在Singleton模式的使用模式應該是:

SQLiteDB* db = [SQLiteDB sharedSQLiteDB]; 

他們的方式,你在呼喚它不適合singelton模式。所有的訪問都應該通過你的sharedSQLiteDB消息。

換句話說,您不應該通過典型的Cocoa模式(SQLiteDB * db = [[[SQLiteDB alloc] init] autorelease];初始化;不正確並且存在問題)。

在使用默認的語言初始化模式(ObjC的alloc/init或C++的默認構造函數)的單例中,應該生成編譯時錯誤消息,因爲應該保護構造函數/ init方法。

查看Wikipedia條目。請參閱Design Pattern C++聖經。甚至有一個版本Cocoa

祝你好運。

0

我強烈建議使用由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]爲您創建。這很漂亮。