0

同様の質問で問題の解決策を見つけることができませんでした。fmdbラッパーを使用してsqliteデータベースから大量のデータを抽出しています。fmdbユーティリティクラスに次のようなメソッドがあります。

  - (NSMutableArray *) getConnectionsForKey: (NSString *) key
 {

     NSString *query = [NSString stringWithFormat:@"select * from user" ];



     FMResultSet *results = [database executeQuery:query];

     NSMutableArray *retArray = [[ NSMutableArray alloc ] init ];

     while ([ results next ]) {

         NSString *fname = [ results stringForColumn:@"firstname" ];
         NSString *lname = [ results stringForColumn:@"lastname" ];


         NSMutableDictionary *aDictionary = [[ NSMutableDictionary alloc ]
                                               init
                                             ];

        [ aDictionary  
          setObject:fname 
          forKey:@"firstname" 
        ]; 

       [ aDictionary 
        setObject:lname 
        forKey:@"lastname" 
       ];



       [ retArray addObject:aDictionary ];

       [ aDictionary release ];


}

[ results close ];

return retArray;
}

それは私の情報を一連の辞書に保存します。ビューコントローラで、次のようにメソッドを呼び出します。

 -(void) setCurrentConnections: (NSString *) key {

   if ( currentConnections != nil ) {
         [ currentConnections removeAllObjects ];
   }

   LocalDatabase *db = [[ LocalDatabase alloc ] init ];

   [ db openDatabase ];

   currentConnections = [ db getConnectionsForKey:key ];

   [ db closeDatabase ];
  [ db release ];


}

これで、このメソッドを呼び出して新しい連絡先で配列を更新するたびに、割り当てツールで観察したときに蓄積し続ける一貫したリークが発生します。これは、データベースからロードした直後にcurrentConnectionsを解放し、このメソッドを再度呼び出さない場合でも発生するため、データベースの実装に問題があると思われます。他の誰かがこの問題を処理しましたか?

4

1 に答える 1

1

currentConnectionsが「setCurrentConnections」でリークしています。これを修正する方法を次に示します(自動解放されたオブジェクトを返すように「getConnectionsForKey」も変更していることに注意してください)。

 - (NSMutableArray *) getConnectionsForKey: (NSString *) key
 {

     NSString *query = [NSString stringWithFormat:@"select * from user" ];
     FMResultSet *results = [database executeQuery:query];

     NSMutableArray *retArray = [[ NSMutableArray alloc ] init ];
     while ([ results next ]) {

         NSString *fname = [ results stringForColumn:@"firstname" ];
         NSString *lname = [ results stringForColumn:@"lastname" ];
         NSMutableDictionary *aDictionary = [[ NSMutableDictionary alloc ] init];

        [ aDictionary  
          setObject:fname 
          forKey:@"firstname" 
        ]; 

       [ aDictionary 
        setObject:lname 
        forKey:@"lastname" 
       ];

       [ retArray addObject:aDictionary ];
       [ aDictionary release ];


       }

[ results close ];

return [retArray autorelease];
}


 -(void) setCurrentConnections: (NSString *) key {

   [ currentConnections removeAllObjects ];
   [ currentConnections release];

   LocalDatabase *db = [[ LocalDatabase alloc ] init ];

   [ db openDatabase ];

   currentConnections = [ db getConnectionsForKey:key ];
   [currentConnections retain];

   [ db closeDatabase ];
  [ db release ];

}

おそらく、への呼び出しをスキップして、removeAllObjectsreleaseを呼び出すことができます。元のコードの問題は、既存のcurrentConnectionへの参照を最初に解放せずに上書きしていたため、リークが発生したことです。

于 2012-02-01T22:06:31.437 に答える