0

我在 ListController 文件中有一个商店列表。我建立了一个 sqlite 数据库,其中存储了 60 家商店。在列表的顶部,我有一个搜索栏。

我创建了一个名为 DataController 的类,它负责加载和存储数据库数据。

@interface DataController : NSObject {
 sqlite3 *database;
 NSArray *shops;    
 NSDictionary* dictionaryOfShops;
}

@property (nonatomic, retain) NSDictionary *dictionaryOfShops;
@property (nonatomic, retain) NSArray* shops;
-(void)initializeShops;

initializeShops 方法从数据库加载数据,并以这种方式将结果存储到 2 个 props 中:

-(void)initializeShops{
    [dictionaryOfShops release];
    [shops release];

    NSMutableDictionary *dictionary = [[[NSMutableDictionary alloc] init] autorelease];

    if (sqlite3_open(....))
    NSString *query = ....
    if (sqlite3_prepare_v2(database, [query UTF8String],-1, &statement, nil) ==   SQLITE_OK) 
    {
        while (sqlite3_step(statement) == SQLITE_ROW) {

           int rId = sqlite3_column_int(statement, 0);
           char *rName = (char *)sqlite3_column_text(statement, 1);

           Shop* s  = [[Shop alloc] init];
           s.ID = rId;
           if(sName != nil) s.Name = [NSString stringWithUTF8String:rName];

               NSString *shopID = [[NSString alloc] initWithFormat:@"%d",s.ID];
           [dictionary setObject:s forKey:shopID];
           [shopID release];
           [s release];         
        }
        sqlite3_finalize(statement);
    }
    [query release];

    dictionaryOfShops = [[NSDictionary alloc] initWithDictionary:dictionary];
    shops =    [[NSArray alloc] initWithArray:[dictionary allValues]];

    dictionary = nil;
    [dictionary release];

       //Sorting
       NSSortDescriptor *sort = [[NSSortDescriptor alloc] initWithKey:@"Name" ascending:YES];
    NSArray *sortedList =[self.shops sortedArrayUsingDescriptors:[NSArray arrayWithObject:sort]];
    self.shops = sortedList; 
    [sort release];
}

问题是当用户在搜索栏中输入一些文本时,我更改了查询的值(添加 LIKE ....),然后再次调用 initializeShops 方法。这第二次造成了很多泄漏,(与 Shop 类属性有关)并且还泄漏了 NSDictionary 和 NSArray。

在将其发布给您之前,我已经尝试了不同的解决方案,但至少在我第一次调用 initilizeShops 时这不会泄漏任何东西。

我接受任何建议,因为我真的坚持下去。

更多的:

真正奇怪的是我的 var 字典和 2 个道具商店和 dictionaryOfShops 的内存管理。使用此代码

NSMutableDictionary *dictionary = [[NSMutableDictionary alloc] init];
//add data to dictionary 
dictionaryOfShops = [[NSDictionary alloc] initWithDictionary:dictionary];
shops =    [[NSArray alloc] initWithArray:[dictionary allValues]];
[dictionary release]

考虑到 dictionaryOfShops 和 shop 是合成的两个属性(非原子,保留),我怎样才能在不泄漏的情况下更改它们的值?

我第一次通过这个方法时,什么都没有泄漏,从第二次开始泄漏这么多对象(集合的内容)。

4

3 回答 3

2

第一个问题是为什么不直接使用 Core Data? 它很可能会更快,需要更少的代码,并且随着时间的推移会更容易维护。直言不讳;SQLite 看似很难。上手容易,做对特别难。

无论如何,内存管理dictionary是错误的。它只是没有崩溃,因为您按照 kennyTM 的建议交换了 nil 分配和释放的顺序。我建议不要创建自动发布的字典。

否则,所写的代码乍一看似乎非常无泄漏。所以:

  1. 你能提供更多的代码吗?其他地方有什么有趣的记忆吗?

  2. 您是否完全使用线程(或 NSOperationQueue)?

  3. 您是否在 Leaks 工具下运行并检索到被泄漏的特定对象的分配回溯?

于 2010-01-09T20:52:46.600 回答
1
dictionary = nil;
[dictionary release];

请交换这两个语句。在这种形式中,它意味着[nil release]哪个是空操作。

于 2010-01-09T20:46:46.940 回答
0

好的,我发现了错误。在我的课堂商店中,我意识到我没有实现该方法

 -(void)dealloc

因此,当我发布旧字典(为新作业做准备)时,其中的所有字段都没有被释放。

于 2010-01-10T15:16:10.570 回答