i've been dancing with a tambourine for a while, but still don't know what's the reason for that error. I've got a tableView with history of user queries data from sqlite base. I'm new to iPhone developing, so my code may be a bit excessive. The hierarchy is:
HistoryModel model-object with some init methods
HistoryDataController gets data from database and presents an array of HistoryModel objects
HistoryViewController subclass of UITableView, displays data
AppDelegate there i initially store an array of HistoryModel objects (by getting it from HistoryDataController) for HistoryViewController to access it.
The problem is, when i scroll the table or open the tab with it for the second time - it crashes with -[CFString retain]: message sent to deallocated instance
Code:
HistoryModel.h pretty unnecessary class for that case, but i want that worked to repeat in several identical cases, but a bit more complicated
@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 i use the entity of that class as getter of data and a storage for HistoryModel objects (in historyEntries property)
@interface HistoryDataController : NSObject {
NSMutableArray *historyEntries;
int limit;
}
@property (nonatomic, retain) NSMutableArray *historyEntries;
@property int limit;
- (id)initWithHistoryData;
- (id)initWithHistoryDataLimitedBy:(int)limit;
HistoryDataController.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 subclass of UITableViewController, gets data stored in AppDelegate's property and displays in the table
@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.h when history tab opens, it gets data of historyList property, that was formed by 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
Fuf. Sorry for so much code, but i believe that's all necessary. As a result of half the day spent on this question, i may guess, that problem is somehow connected with HistoryModel entity, because when i delete "retain" for word @property, the error switches for -[CFString isEqualToString:]: message sent to deallocated instance
I'm not really experienced in memory management, but i guess this HistoryModel objects inside historyEntry in HistoryViewController or in historyList in AppDelegate releases somehow, when scrolling the table or opening the tab for the second time. But this's just my guessing. Really appreciate the help.