单例未正确初始化

发布于 2024-11-04 19:24:44 字数 1023 浏览 0 评论 0原文

我有使用此语句调用的以下代码: SQLiteDB *db = [[[SQLiteDB alloc] init] autorelease];

问题是“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
}

I have the following code that I am calling using this statement: SQLiteDB *db = [[[SQLiteDB alloc] init] autorelease];

The problem is "sharedSQLiteDB" is not being called, but rather "allocWithZone" is, and therefore "checkIfDatabaseExists" is not being called, which is where the database is created.

I don't understand why... (i.e. what am I doing wrong?)

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

暗恋未遂 2024-11-11 19:24:44

在单例模式中,您的使用模式应该是:

SQLiteDB* db = [SQLiteDB sharedSQLiteDB];

您调用它的方式不适合单例模式。所有访问都应该通过您的共享SQLiteDB消息进行。

换句话说,您不应该在类的范围之外通过典型的 Cocoa 模式进行初始化(SQLiteDB *db = [[[SQLiteDB alloc] init] autorelease]; 是不正确且充满问题的)。

在使用语言默认初始化模式(ObjC 的 alloc/init 或 C++ 的默认构造函数)的单例中,应该生成编译时错误消息,因为构造函数/init 方法应该受到保护。

请参阅维基百科条目。请参阅设计模式 C++ 圣经。甚至还有一个 Cocoa 的版本

祝你好运。

In the singleton pattern your use pattern should be:

SQLiteDB* db = [SQLiteDB sharedSQLiteDB];

They way you are calling it doesn't fit the singelton pattern. All access should be through your sharedSQLiteDB message.

In other words you shouldn't be initializing via typical Cocoa patterns (SQLiteDB *db = [[[SQLiteDB alloc] init] autorelease]; is incorrect and full of problems) outside the scope of the class.

In a singleton using the default initialization pattern for the language (alloc/init for ObjC or the default constructor for C++) should generate a compile time error message since the constructor/init method should be protected.

See the Wikipedia entry. consult the Design Pattern C++ bible. There is even a version for Cocoa

Good luck.

所有深爱都是秘密 2024-11-11 19:24:44

它不会执行您的 + (SQLiteDB *)sharedSQLiteDB 方法,因为您实际上并未在任何地方调用该方法。

正如您所看到的,当您调用[[SQLiteDB alloc] init]时,会调用allocWithZone方法。

将您的调用更改为 SQLiteDB *db = [SQLiteDB sharedSQLiteDB],在本例中它将调用您的 checkIfDatabaseExists 方法。但是,如果在其他地方调用[[SQLiteDB alloc] init],则仍会跳过checkIfDatabaseExists方法调用。

也许可以考虑将 checkIfDatabaseExists 方法移动到 init 方法中,以便为您的单例方法和 allocWithZone 调用它。

It isn't executing your + (SQLiteDB *) sharedSQLiteDB method because you're not actually calling that method anywhere.

As you've seen, when you call [[SQLiteDB alloc] init], the allocWithZone method is called.

Change your call to be SQLiteDB *db = [SQLiteDB sharedSQLiteDB], which will call your checkIfDatabaseExists method in this case. However, if [[SQLiteDB alloc] init] is called somewhere else, then the checkIfDatabaseExists method call will still be skipped.

Maybe consider moving the checkIfDatabaseExists method into an init method so that it will be called for both your singleton method and your allocWithZone.

东风软 2024-11-11 19:24:44

老实说我没有看到任何错误......
不过,我发布了用于创建单例的代码。它来自一个来源,现在我不记得链接了......这不是我的代码。

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

我希望它有帮助

Honestly I don't see any error...
However I post the code I used to create a Singleton. It's from a source that now I don't remember the link... it's not my code.

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

I hope it helps

天冷不及心凉 2024-11-11 19:24:44

我强烈建议使用 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] 已为您创建。非常甜蜜。

I highly recommend using the SyntesizeSingleton header file first created by Matt Gallagher.

Find the latest version (that I know about) here:

https://github.com/cjhanson/Objective-C-Optimized-Singleton

It makes creating a singleton dead simple.

Here's an example header:

#import <Foundation/Foundation.h>
@interface Example : NSObject {}
+(Example*)sharedExample;
@end

And the corresponding .m:

#import "FMUser.h"
#import "SynthesizeSingleton.h"
@implementation Example
SYNTHESIZE_SINGLETON_FOR_CLASS(Example);
@end

[Example sharedExample] is created for you. It's pretty sweet.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文