ListControllerファイルにショップのリストがあります。私はsqliteデータベースをセットアップしました。そこには60のショップが保存されています。リストの一番上に検索バーがあります。
dbデータのロードと保存を担当するDataControllerというクラスを作成しました。
@interface DataController : NSObject {
sqlite3 *database;
NSArray *shops;
NSDictionary* dictionaryOfShops;
}
@property (nonatomic, retain) NSDictionary *dictionaryOfShops;
@property (nonatomic, retain) NSArray* shops;
-(void)initializeShops;
initializeShopsメソッドは、データベースからデータをロードし、次のように結果を2つの小道具に保存します。
-(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メソッドを再度呼び出すことです。この2回目は、(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とshopsが2つのプロパティ(非アトミック、保持)で合成されていることを考えると、リークなしで値を変更するにはどうすればよいですか?
このメソッドを最初に通過したときは何もリークされません。2回目からは非常に多くのオブジェクト(コレクションのコンテンツ)がリークし始めます。