2010-09-10 2 views
0

Я искал высоко и низко, чтобы попытаться устранить эту утечку памяти, но я не могу понять, как ее уйти. У меня есть несколько классов, которые я использую для подключения к моей базе данных sqlite и получения информации.Утечка памяти в объекте C Класс iOS

Когда я запускаю приложение с помощью инструментов производительности, утечек, я все время считаю, что все мои классы утечки памяти.

Ниже приведен код, который у меня есть. Любая помощь, разрешающая эту утечку, будет с благодарностью оценена.

tbl_materialsList.h

@interface tbl_materialsList : NSObject { 

NSInteger materialListID; 
NSString *shoppingListID; 
NSString *projectID; 
NSString *materialName; 
NSString *numberOfUnits; 
NSString *purchased; 
NSString *totalPrice; 
NSString *unitPrice; 

} 

@property (nonatomic, readonly) NSInteger materialListID; 
@property (nonatomic, retain) NSString *shoppingListID; 
@property (nonatomic, retain) NSString *projectID; 
@property (nonatomic, retain) NSString *materialName; 
@property (nonatomic, retain) NSString *numberOfUnits; 
@property (nonatomic, retain) NSString *purchased; 
@property (nonatomic, retain) NSString *totalPrice; 
@property (nonatomic, retain) NSString *unitPrice; 

- (id)getDataToDisplay:(NSString *)dbPath :(NSString *)selectStatement; 
- (void)saveData:(NSString *)dbPath :(NSString *)selectStatement; 
- (id)initWithPrimaryKey:(NSInteger)pk; 

tbl_materialsList.m

- (id)getDataToDisplay:(NSString *)dbPath :(NSString *)selectStatement { 


// Init the data Array 
NSMutableArray *data = [[NSMutableArray alloc] init]; 

if (sqlite3_open([dbPath UTF8String], &database) == SQLITE_OK) { 

    NSString *sql = selectStatement; //"select * from tbl_projects"; 
    sqlite3_stmt *selectstmt; 
    if(sqlite3_prepare_v2(database, [sql UTF8String], -1, &selectstmt, NULL) == SQLITE_OK) { 
    //loop thru and fill the array 
    while(sqlite3_step(selectstmt) == SQLITE_ROW) { 
    //reading the results 
    NSInteger primaryKey = sqlite3_column_int(selectstmt, 0); 
    tbl_materialsList *listObj = [[tbl_materialsList alloc] initWithPrimaryKey:primaryKey]; 
    listObj.shoppingListID = [NSString stringWithUTF8String:(char *)sqlite3_column_text(selectstmt, 1)]; 
    listObj.projectID = [NSString stringWithUTF8String:(char *)sqlite3_column_text(selectstmt, 2)]; 
    listObj.materialName = [NSString stringWithUTF8String:(char *)sqlite3_column_text(selectstmt, 3)]; 
    listObj.numberOfUnits = [NSString stringWithUTF8String:(char *)sqlite3_column_text(selectstmt, 4)]; 
    listObj.purchased = [NSString stringWithUTF8String:(char *)sqlite3_column_text(selectstmt, 5)]; 
    listObj.totalPrice = [NSString stringWithUTF8String:(char *)sqlite3_column_text(selectstmt, 6)]; 
    listObj.unitPrice = [NSString stringWithUTF8String:(char *)sqlite3_column_text(selectstmt, 7)]; 

    [data addObject:listObj]; 
    [listObj release]; 
    } 
    } 

    //release the compiled statment from memory 
    sqlite3_finalize(selectstmt); 

} 

sqlite3_close(database); //Even though the open call failed, close the database connection to release all the memory. 

return data; 

} 

ответ

0

строки должны быть @property(nonatomic,copy) в первую очередь, и вы должны освободить данные. [data release];

+0

Зачем им нужно «копировать», а не «сохранять»? –

+0

@Graham - Единственная причина, по которой я слышал, потому что возможно, что вы указали свое сохранение на NSMutableString, которое затем может быть изменено из-под вас. Копирование предотвращает это. Я не уверен, почему люди сосредоточены на этой проблеме (которая существует с любой сохраненной ссылкой) специально для NSString. – Peter

+0

Ненавижу звучать глупо, но если я выпущу данные после возвращения, кажется, что ничего не происходит. Когда я просматриваю код, он все еще имеет все свои объекты. Если я выпущу раньше, он сработает, как я ожидал. –

1

Включает ли ваш tbl_materialslist объект dealloc, который устанавливает все ваши сохраняемые свойства в нуль? Если нет, все они протекают, хотя ваш listObj освобождается.

+0

Привет, спасибо за быстрый ответ. Я делаю следующее ... - (void) dealloc { \t [ релиз shoppingListID]; \t [ProjectID релиз]; \t [materialName релиз]; \t [NumberofUnits релиз]; \t [купил relea SE]; \t [итогоPrice выпуск]; \t [unitPrice release]; \t [super dealloc]; } –

+0

Это выглядит хорошо для меня. Шейхан прав, что вы также должны выпускать данные. – Peter

3

Ваша последняя строка:

return data; 

должно быть:

return [data autorelease]; 

Если, конечно, вы не намерены объект будет принадлежать вызывающему возвращаемые данные, то вы должны сделать имя метода соответствуют соглашениям об именах Objective-C в этом методе, которые возвращают объекты со значением сохранения +1, должны содержать одно из слов «copy» «create» или «new»;

Но я подозреваю, что это не то, что вы намерены.

+0

когда я возвращаю [данные autorelease]; приложение выйдет из строя. Я в основном получаю эти данные и загружаю их в NSMutableArray и использую для отображения списка материалов в таблице. Когда я смотрю в прибор для утечки, он показывает, что 100% находится во время разговора, а затем, когда я перехожу к этому коду, он показывает разные проценты в каждом из списка: имя_обмена.materialName, itemCost и т. Д. –

+0

После создания [autorelease] изменения, вам также необходимо сохранить результирующий объект данных в методе, вызывающем getDataToDisplay, а затем убедитесь, что он правильно освобожден, когда вы закончите с ним. – logancautrell

+0

Вызов, который я делаю, - tbl_materialsList * dbaseTable = [[tbl_materialsList alloc] init]; \t NSString * statement = [NSString stringWithFormat: @ "select * from tbl_materialsList где projectID =% d", projectData.projectID]; \t NSArray * data = [dbaseTable getDataToDisplay: [appDelegate getDBPath]: statement]; Я всегда думал, что данные будут автореализоваться ... –

0

неродственного совет:

Никогда не возвращать объект как(id), если это не абсолютно необходимо. Например, ваш getDataToDisplay:: должен быть

-(NSMutableArray*)getDataToDisplay:(NSString *)dbPath :(NSString *)selectStatement; 

Таким образом, вы можете получить больше предупреждений компилятора, когда вы делаете ошибку.

Я думаю, есть книга программирования iPhone, которая продвигает этот плохой обычай. Автору книги следует пометить, и книга должна быть сожжена ...: p

Смежные вопросы