ios singleton class crashes my app

后端 未结 3 1120
一整个雨季
一整个雨季 2021-01-26 06:18

I have a problem with an singleton pattern.

I have read the following tutorials about singleton classes and have created my own. http://www.galloway.me.uk/utorials/sing

相关标签:
3条回答
  • The solution of Jano must work well. I use this way too to create singleton object. And I don't have any problem.

    For your code, I think that if you use @synchronized (it's not necessary cause your have dispatch_once_t as Jano said), you should not call return in @synchronized.

    + (BPManager *) bpManager {
        @synchronized(self) {
            if(sharedMyManager == nil) {
                static dispatch_once_t pred;        // Lock
                dispatch_once(&pred, ^{             // This code is called at most once per app
                    sharedMyManager = [[BPManager alloc] init];
                });
            } 
        }
    
        return sharedMyManager;
    }
    
    0 讨论(0)
  • 2021-01-26 07:09

    How about

    @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];
    

    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.

    0 讨论(0)
  • 2021-01-26 07:09

    I'm not sure whether it's the (complete) answer, but one major flaw is that you're using instance variables (self, super) in a class method, +(id)bpManager; I'm actually surprised it let you compile that at all. Change the @synchronized(self) to @synchronized(sharedMyManager), and the [[super alloc...] init] to [[BPManager alloc...] init]. And, writing that just made me realize that the problem looks like accessing a subclassed method on an object instantiated as the superclass, but that should have been overwritten in the dispatch. Shouldn't you really only need one of those anyway, why double-init like that? (And while we're there, that's a memory leak - init'd in the if() and then overwritten in the closure without releasing it.)

    0 讨论(0)
提交回复
热议问题