1

。という名前のシングルトンクラスを作成しましたDataManager。キャッシュを設定しました。ただし、の別のインスタンスメソッド内からキャッシュインスタンスメソッドを呼び出そうとすると、次の行でエラーDataManagerが発生します。EXC_BAD_ACCESS

NSMutableArray *stops = [[DataManager sharedInstance] getCacheForKey:@"stops"];

DataManager.h

@interface DataManager : NSObject {
    FMDatabase *db;
    NSMutableDictionary *cache;
}

+ (DataManager *)sharedInstance;
// ... more methods
- (id)getCacheForKey:(NSString *)key;
- (void)setCacheForKey:(NSString *)key withValue:(id)value;
- (void)clearCache;

DataManager.m

- (NSArray *)getStops:(NSInteger)archived {
    NSMutableArray *stops = [[DataManager sharedInstance] getCacheForKey:@"stops"];
    if (stops != nil) {
        NSLog(@"Stops: %@", stops);
        return stops;
    }

    stops = [NSMutableArray array];
    // set stops...

    [[DataManager sharedInstance] setCacheForKey:@"stops" withValue:stops];

    return stops;
}

別のViewControllerから呼び出されたときに発生するようです。これは、エラーのない最初のビューコントローラ、エラーのない2番目のビューコントローラです。

これはシングルトンでの私の最初の試みなので、私は単純な間違いを犯していると確信しています。しかし、私はそれを自分で見ることができません。

注:[self getCache...]同じ結果で試しました。

アップデート

これが私のシングルトン実装です。http://www.galloway.me.uk/tutorials/singleton-classes/から適応

+ (DataManager *)sharedInstance {
    @synchronized(self) {
        if (!instance) {
            instance = [[super allocWithZone:NULL] init];
        }
    }

    return instance;
}

+ (id)allocWithZone:(NSZone *)zone {
    return [[self sharedInstance] retain];
}

- (id)copyWithZone:(NSZone *)zone {
    return self;
}

- (id)retain {
    return self;
}

- (unsigned)retainCount {
    return UINT_MAX;
}

- (oneway void)release {
    // never release
}

- (id)autorelease {
    return self;
}

- (id)init {
    if (self = [super init]) {        
        if (db == nil){
            BourbonAppDelegate *appDelegate = (BourbonAppDelegate *)[[UIApplication sharedApplication] delegate];
            [appDelegate createEditableCopyOfDatabaseIfNeeded];
            db = [[FMDatabase alloc] initWithPath:[appDelegate getDBPath]];
        }

        if (![db open]) {
            NSAssert(0, @"Failed to open database.");
            [db release];

            return nil;
        }

        [db setTraceExecution:YES];        
        [db setLogsErrors:TRUE];

        cache = [NSMutableDictionary dictionary];
        NSLog(@"cache: %@", cache);
    }

    return self;
}
4

2 に答える 2

5

cacheオブジェクトは自動解放されるため、アクセスしようとするとメモリに存在しなくなります。

[NSMutableDictionary alloc] init]代わりにを使用[NSMutableDictionary dictionary]して、保持されるインスタンスを取得します。

于 2012-07-01T16:13:53.277 に答える
4

すでに回答されているあなたの質問に対する直接の回答ではありません。

ただし、シングルトンの実装は最適ではないことを指摘したいと思います。@synchronizedは非常に高価であり、シングルトンにアクセスするたびに使用することを避けることができます。

if (!instance) {
    @synchronized(self) {
        if (!instance) {
            instance = [[super allocWithZone:NULL] init];
        }
    }
}

シングルトンを初期化するさらに良い方法は次のとおりです。

+ (DataManager *)sharedInstance {
    static DataManager *instance;

    static dispatch_once_t donce;
    dispatch_once(&donce, ^{
        instance = [[self alloc] init];
    });

    return instance;
}
于 2012-07-01T16:21:25.610 に答える