Я танцевал с тамбурином какое-то время, но до сих пор не знаю, в чем причина этой ошибки. У меня есть таблицаView с историей пользовательских запросов данных из базы sqlite. Я новичок в разработке iPhone, поэтому мой код может быть немного чрезмерным. Иерархия:таблица прокрутки: сообщение отправлено на освобожденный экземпляр
HistoryModel модель-объект с некоторыми методами инициализации
HistoryDataController получает данные из базы данных и представляет собой массив HistoryModel объектов
HistoryViewController подкласс UITableView отображает данные
AppDelegate там я изначально хранить массив объектов HistoryModel (получая его от HistoryDataController) для HistoryViewController доступа к нему.
Проблема заключается в том, когда я прокручивать таблицу или открыть вкладку с ним во второй раз - он выходит из строя с - [CFString сохранить]: сообщение, отправленное высвобождены например
код :
HistoryModel.h довольно ненужный класс для этого случая, но я хочу, что работал, чтобы повторить в нескольких одинаковых случаях, но немного сложнее
@interface HistoryModel : NSObject {
int entry_id;
NSString *word;
}
- (id)initWithWord:(NSString *)word;
- (id)initWithWord:(NSString *)word andId:(int)entry_id;
@property int entry_id;
@property (retain) NSString *word;
@end
HistoryModel.m
@implementation HistoryModel
@synthesize entry_id, word;
- (id)initWithWord:(NSString *)_word {
[super init];
word = _word;
return self;
}
- (id)initWithWord:(NSString *)_word andId:(int)_entry_id {
entry_id = _entry_id;
return [self initWithWord:_word];
@end
HistoryDataController.h я использовать объект этого класса в качестве геттера данных и хранилище для объектов HistoryModel (в historyEntries собственности)
@interface HistoryDataController : NSObject {
NSMutableArray *historyEntries;
int limit;
}
@property (nonatomic, retain) NSMutableArray *historyEntries;
@property int limit;
- (id)initWithHistoryData;
- (id)initWithHistoryDataLimitedBy:(int)limit;
ИсторияDataController.m
@implementation HistoryDataController
@synthesize historyEntries, limit;
- (id)initWithHistoryDataLimitedBy:(int)_limit {
[super init];
// Getting data from database
{some DB stuff}
NSMutableArray *tmp_historyEntries = [[NSMutableArray alloc] init];
while(result == SQLITE_ROW)
{
HistoryModel *currentHistoryEntry = [[HistoryModel alloc] initWithWord:[NSString stringWithUTF8String:(char *)sqlite3_column_text(statement, 1)] ];
[tmp_historyEntries addObject:currentHistoryEntry];
result = sqlite3_step(statement);
}
historyEntries = tmp_historyEntries;
{some DB stuff}
return self;
}
@end
HistoryViewController.h подкласс UITableViewController, получает данные, хранящиеся в свойстве AppDelegate и отображает в таблице
@interface HistoryViewController : UITableViewController {
IBOutlet UITableView *historyTable;
SynonymsAppDelegate *appDelegate;
}
@property (retain) UITableView *historyTable;
@end
HistoryViewController.m
@implementation HistoryViewController
@synthesize historyTable, historyEntriesToShow;
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
appDelegate = (SynonymsAppDelegate *)[[UIApplication sharedApplication] delegate];
[appDelegate initHistoryList];
[self.tableView reloadData];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
{standart cell stuff}
HistoryModel *historyEntry = [appDelegate.historyList objectAtIndex:indexPath.row];
cell.textLabel.text = historyEntry.word;
return cell;
}
@end
SynonymsAppDelegate.ч при открытии вкладки истории, она получает данные historyList имущества, которое было сформировано по HistoryDataController :)
@interface SynonymsAppDelegate : NSObject <UIApplicationDelegate, UITabBarControllerDelegate> {
...
NSMutableArray *historyList;
}
...
@property (retain) NSMutableArray *historyList;
- (void)initHistoryList;
@end
SynonymsAppDelegate.m
@implementation SynonymsAppDelegate
@synthesize window, tabBarController, historyList;
- (void)initHistoryList {
HistoryDataController *historyDataController = [[HistoryDataController alloc] initWithHistoryData];
historyList = historyDataController.historyEntries;
}
@end
Фуф. Извините за столько кода, но я считаю, что все это необходимо. В результате половины дня, потраченного на этот вопрос, я могу догадаться, эта проблема каким-то образом связана с объектом HistoryModel, потому что когда я удаляю «сохранить» для слово @property, ошибка переключается на - [CFString isEqualToString: ]: сообщение, отправленное высвобождены например
Я не очень опытный в управлении памятью, но я предполагаю, что это HistoryModel объекты внутри historyEntry в HistoryViewController или historyList в AppDelegateвыпускает как-то, прокручивая стол или открывая вкладку во второй раз. Но это только мои догадки. Действительно оцените помощь.
Довольно длинные, но важные части отсутствуют. Для свойств NSString вы почти всегда хотите (копировать) вместо сохранения. Может оказаться полезным дополнительный код для вашей HistoryModel. Вероятно, код находится в другом месте, хотя, возможно, релиз для автореализованной NSString. – Eiko
Не знаю, если это проблема, но я думаю, вам нужно сохранить в appDelegate: historyList = [historyDataController.historyEntries сохранить]; – Rengers
Спасибо, я попробовал все, что вы предложили, но это не решило проблему. Для Eiko: это все код HistoryModel, который у меня есть, за исключением методов init, которые, как я уже упоминал, все равно не используются. Rengers, я попробовал ваше решение, это не помогло, но я постараюсь сохранить другие объекты. На самом деле, я еще не занимался управлением памятью, потому что я не знаком с этим, и это только начало программы. – nikans