J'ai dansé avec un tambourin pendant un moment, mais je ne sais toujours pas quelle est la raison de cette erreur. J'ai une tableView avec l'historique des requêtes des utilisateurs de sqlite base. Je suis nouveau sur iPhone en développement, donc mon code peut être un peu excessif. La hiérarchie est la suivante:table déroulante: message envoyé à l'instance désaffectée
HistoryModel modèle-objet avec certains procédés d'initialisation
HistoryDataController obtient des données à partir de la base de données et présente un tableau d'objets HistoryModel
HistoryViewController sous-classe de UITableView, affiche les données
AppDelegate il i stocker d'abord un tableau d'objets HistoryModel (en l'obtenant HistoryDataController) pour HistoryViewController pour y accéder.
Le problème est, quand je défiler la table ou ouvrir l'onglet avec elle pour la deuxième fois - il se bloque avec - [CFString retain]: message envoyé à l'instance désallouées
code :
HistoryModel.h classe assez inutile pour ce cas, mais je veux que travaillé à répéter dans plusieurs cas identiques, mais un peu plus compliqué
@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 utilise l'entité de cette classe en tant que getter de données et une mémoire pour les objets HistoryModel (en propriété historyEntries)
@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 sous-classe de UITableViewController, obtient des données stockées dans la propriété de AppDelegate et affiche dans le tableau
@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 lorsque onglet Historique ouvre, il obtient des données de la propriété HistoryList, qui a été formé par 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. Désolé pour tant de code, mais je crois que tout est nécessaire. En raison de la moitié de la journée passée sur cette question, je devine, ce problème est en quelque sorte lié à l'entité HistoryModel, car lorsque je supprime "conserver" pour mot @property, l'erreur bascule pour - [CFString isEqualToString: ]: message envoyé à l'instance désallouées
Je ne suis pas vraiment expérimenté dans la gestion de la mémoire, mais je suppose que ce HistoryModel objets à l'intérieur historyEntry dans HistoryViewController ou HistoryList dans AppDelegatesort en même temps lorsque vous faites défiler le tableau ou ouvrez l'onglet pour la deuxième fois. Mais c'est juste ma deviner. Vraiment apprécier l'aide.
Des pièces assez longues et pourtant importantes manquent. Pour les propriétés NSString, vous voulez presque toujours (copier) au lieu de conserver. Plus de code pour votre HistoryModel pourrait être utile. Probablement le code est ailleurs, cependant - peut-être une libération à un NSString autoreleased. – Eiko
Ne sait pas si c'est le problème, mais je pense que vous avez besoin d'un retenir dans votre appDelegate: historyList = [historyDataController.historyEntries conserver]; – Rengers
Merci, j'ai essayé tout ce que vous avez proposé, mais cela n'a pas résolu le problème. Pour Eiko: c'est tout le code de HistoryModel que j'ai, sauf pour les méthodes init, qui, comme je l'ai mentionné, ne sont pas utilisées de toute façon. Rengers, j'ai essayé ta solution, ça n'a pas aidé mais j'essaierai de retenir d'autres objets. En fait, je n'ai pas encore fait de gestion de la mémoire, parce que je n'ai pas d'expérience et c'est juste le début du programme. – nikans