ios singleton类崩溃了我的应用程序 [英] ios singleton class crashes my app

查看:77
本文介绍了ios singleton类崩溃了我的应用程序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我遇到单例模式的问题。

I have a problem with an singleton pattern.

我已阅读以下有关单例类的教程并创建了自己的类。
http://www.galloway.me.uk/utorials/singleton-班级/
http://www.johnwordsworth.com/2010/04/iphone-code-snippet-the-singleton-pattern/

I have read the following tutorials about singleton classes and have created my own. http://www.galloway.me.uk/utorials/singleton-classes/ http://www.johnwordsworth.com/2010/04/iphone-code-snippet-the-singleton-pattern/

我第一次建立&运行它应用的应用程序。没问题!
但是当我重建应用程序时,单例类不再正常工作了。第一个init就像它应该的那样工作,但是当我点击按钮后再次调用它时会崩溃我的应用程序。

The first time i build & run the app it works like it should. No problems at all! But when i rebuild the app the singleton class does not work properly anymore. The first init works like it should but when i call it again after a button click it crashes my app.

我的单身类:

BPManager.h

BPManager.h

@interface BPManager : NSObject {
    NSString *dbPath;
}

@property (nonatomic, retain) NSString *dbPath;

+ (id)bpManager;
- (void)initDatabase:(NSString *)dbName;
- (int)getQuestions;

@end

BPManager.m

BPManager.m

static BPManager *sharedMyManager = nil;

@implementation BPManager

@synthesize dbPath;

- (void)initDatabase:(NSString *)dbName
{   
    dbPath = dbName;
}
-(int)getQuestions
{
    NSLog(@"getQuestions");
}


- (id)init {
    if ((self = [super init])) {
    }
    return self;
}

+ (BPManager *) bpManager {
    @synchronized(self) {

        if(sharedMyManager != nil)  return sharedMyManager;

        static dispatch_once_t pred;        // Lock
        dispatch_once(&pred, ^{             // This code is called at most once per app
            sharedMyManager = [[BPManager alloc] init];
        });
    }

    return sharedMyManager;
}

- (void)dealloc {
    [dbPath release];
    [super dealloc];
}

当我在构建界面时调用以下代码时,应用程序会创建单例:

When i call the following code when building my interface, the app creates the singleton:

BPManager *manager = [BPManager bpManager];
[manager initDatabase:@"database.db"];

注意:此时我也可以从其他文件创建对该类的引用。但是,当我点击一个按钮时,它似乎松开了他的参考。

Note: At this point i can create references to the class from other files as well. But when i click on a button it seems to loose his references.

但是当点击一个按钮时,下面的代码是ecexuted:

But when a button is clicked, the following code is ecexuted:

BPManager *manager = [BPManager bpManager];
int count = [manager getQuestions];

该应用应获取sharedInstance。这样做,只有参数(如dbPath)不可访问。为什么会这样?

The app should get the sharedInstance. That works, only the parameters (like dbPath) are not accessible. Why is that?

经过一番研究后,我将方法改为:

after some research, i have changed the method to:

+ (BPManager *) bpManager {
    @synchronized(self) {

        if(sharedMyManager != nil)  return sharedMyManager;

        static dispatch_once_t pred;        // Lock
        dispatch_once(&pred, ^{             // This code is called at most once per app
            sharedMyManager = [[BPManager alloc] init];
        });
    }

    return sharedMyManager;
}

但问题未解决

推荐答案

怎么样

@interface BPManager : NSObject
@property (nonatomic, copy) NSString *dbName;
@property (nonatomic, assign) int questions;
-(id) initWithDBName:(NSString*) dbName {
@end

#import "BPManager.h"
@implementation BPManager
@synthesize dbName=_dbName, questions;
+(BPManager *)singleton {
    static dispatch_once_t pred;
    static BPManager *shared = nil;
    dispatch_once(&pred, ^{
        shared = [[BPManager alloc] initWithDBName:@"database.db"];
    });
    return shared;
}
-(id) initWithDBName:(NSString*) dbName {
    self = [super init]
    if (self) self.dbName = dbName;
    return self;
}
-(void)dealloc {   
    [_dbName release];
    [super dealloc];
}
@end

BPManager *manager = [BPManager singleton];
int count = [manager questions];

静态对于实现文件是私有的,但没有理由在单例方法之外甚至可以访问它。 init使用默认实现覆盖默认实现,因此它没用。在Objective-C中,使用var name(count)命名getter,而不是getCount。初始化类两次会导致未定义的行为。当您已经使用dispatch_once时,无需同步或检查if == nil,请参阅单身人士的照顾和喂养。 NSString应始终使用copy而不是@property中的保留。你不需要dealloc,因为这将在你的应用程序运行时永远保持活跃状态​​,但它就是你想要将这个类用作非单例的情况。你可能也很好,这个班级在你的代表中是一个ivar而不是单身,但你可以两种方式。

The static is private to the implementation file but no reason it should be even accessible outside the singleton method. The init overrides the default implementation with the default implementation so it's useless. In Objective-C you name the getter with the var name (count), not getCount. Initializing a class twice causes an undefined behaviour. No need to synchronize or check for if==nil when you are already using dispatch_once, see Care and Feeding of Singletons. NSString should always use copy instead retain in @property. You don't need the dealloc because this is going to be active forever while your app is running, but it's just there in case you want to use this class as a non singleton . And you probably are as good with this class being an ivar in your delegate instead a singleton, but you can have it both ways.

这篇关于ios singleton类崩溃了我的应用程序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆