Это дополнительный вопрос из моего предыдущего, касающийся того, почему мой managedObjectContext возвращался к нулю.Я думал, что направление вопроса будет скрыто в старом.
Теперь я получаю mangedObjectContext , чтобы не возвращать ноль, и при выполнении [outlineView reloadData]
с моим outlineView вообще ничего не происходит,Я попытался выборочно удалить части кода, предназначенные для обновления outlineView , чтобы увидеть, если что-то изменится, и ответ - нет.С тех пор я узнал (после того как я написал этот вопрос изначально), что моя связь с источником данных исчезает на каком-то этапе.
Примечания:
- приведенный ниже код запускается один раз на awakeFromNibкласса источника данных и работает отлично.
- Именно при вызове его в любое другое время возникает моя проблема.Я не получаю ошибок отладки, но мой outlineView остается неизменным.
- Я сузил это до работы на NSLog
[outlineView dataSource]
.Когда метод вызывается из awakeFromNib
, он возвращает dataSource как мой dataSourceClass правильно.Каждый раз, когда он возвращает источник данных как nil . - , dataSourceClass был привязан к outlineView в InterfaceBuilder .
- Все другие проверки NSLog I 'Внесенные в объект обновления в массивах моего кода возвращаются, как и ожидалось, с правильными обновлениями.Фактически, я проверил окончательные projectsArray и clientsArray , и они содержат все новые объекты, введенные перед попыткой создания узлов в outlineView.
- Я использую стандартныйсгенерированный xcode код делегата приложения для основных данных.
- Я не использую
NSTreeController
и использую свой собственный NSOutlineViewDataSource
.Было невозможно (или не задокументировано), как заполнить outlineView на основе родительских / дочерних отношений двух сущностей базовых данных. - Я также включу свой
NSOutlineViewDataSource
код ниже.
Обновления:
Обновление 1: Хммм ... как раз перед тем, как позвонить [outlineView reloadData]
Я попробовал NSLog
для [outlineView dataSource]
, и он вернулся как ноль .Я изначально связал источник данных с outlineView с помощью привязок в interfaceBuilder .Теперь я предполагаю, что это моя проблема.Почему освобождается мой источник данных?и как мне вернуть его, если я не могу предотвратить его выпуск?
Код:
refreshOutLineView:
rootNode = [[IFParentNode alloc] initWithTitle:@"Root" children:nil];
NSInteger clientCounter;
clientCounter = 0;
NSFetchRequest *clientsFetchRequest = [[NSFetchRequest alloc] init];
NSManagedObjectContext *clientsMoc = [clientsController managedObjectContext];
NSLog(@"clientsMoc is : %@", clientsMoc);
if(clientsMoc == nil) {
NSLog(@"And, yes, clientsMoc is = nil");
clientsMoc = [(Voiced_AppDelegate *)[[NSApplication sharedApplication] delegate] managedObjectContext];
NSLog(@"After managedObjectContext: %@", clientsMoc);
}
NSEntityDescription *clientsEntity = [NSEntityDescription entityForName:@"Clients" inManagedObjectContext:clientsMoc];
//NSLog(@"clientsEntity, after the 'if nil' code is now: %@", clientsEntity);
[clientsFetchRequest setEntity:clientsEntity];
//sort
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"clientCompany" ascending:YES];
NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil];
[clientsFetchRequest setSortDescriptors:sortDescriptors];
NSError *clientsFetchError = nil;
clientsArray = [clientsMoc executeFetchRequest:clientsFetchRequest error:&clientsFetchError];
[clientsFetchRequest release];
//NSLog(@"clientsArray, after fetching is now: %@", clientsArray);
NSInteger projectCounter;
projectCounter = 0;
NSFetchRequest *projectsFetchRequest = [[NSFetchRequest alloc] init];
NSManagedObjectContext *projectsMoc= [projectsController managedObjectContext];
if(projectsMoc == nil) {
NSLog(@"And, yes, projectsMoc is = nil");
projectsMoc = [(Voiced_AppDelegate *)[[NSApplication sharedApplication] delegate] managedObjectContext];
NSLog(@"After managedObjectContext: %@", projectsMoc);
}
NSEntityDescription *projectsEntity = [NSEntityDescription entityForName:@"Projects" inManagedObjectContext:projectsMoc];
[projectsFetchRequest setEntity:projectsEntity];
NSError *projectsFetchError = nil;
projectsArray = [projectsMoc executeFetchRequest:projectsFetchRequest error:&projectsFetchError];
[projectsFetchRequest release];
//NSLog(@"projectsArray, after fetching is now: %@", projectsArray);
for (NSString *s in clientsArray) {
NSManagedObject *clientMo = [clientsArray objectAtIndex:clientCounter]; // assuming that array is not empty
id clientValue = [clientMo valueForKey:@"clientCompany"];
//NSLog(@"Company is %@", parentValue);
IFParentNode *tempNode = [[IFParentNode alloc] initWithTitle:[NSString stringWithFormat:@"%@", clientValue] children:nil];
clientCounter = clientCounter + 1;
[rootNode addChild:tempNode];
[tempNode release];
}
for (NSString *s in projectsArray) {
NSInteger viewNodeIndex;
viewNodeIndex = 0;
NSManagedObject *projectMo = [projectsArray objectAtIndex:projectCounter]; // assuming that array is not empty
id projectValue = [projectMo valueForKey:@"projectTitle"];
id projectParent = [[projectMo valueForKey:@"projectParent"] valueForKey: @"clientCompany"];
// find if theres an item with the projetParent name
id nodeTitle = [[rootNode children] valueForKey:@"title"];
for(NSString *companies in nodeTitle) {
if([companies compare:projectParent] == NSOrderedSame) {
//NSLog(@"Company is %@ and parent is %@ and id is: %d", companies, projectParent, viewNodeIndex);
// then assign that node to be the tempnode.
IFParentNode *tempNode = [rootNode.children objectAtIndex:viewNodeIndex];
IFChildNode *subTempNode = [[IFChildNode alloc] initWithTitle:[NSString stringWithFormat:@"%@", projectValue]];
[tempNode addChild:subTempNode];
[subTempNode release];
[tempNode release];
} else {
// do nothing.
}
viewNodeIndex = viewNodeIndex + 1;
}
projectCounter = projectCounter + 1;
}
[outlineView expandItem:nil expandChildren:YES];
[outlineView reloadData];
}
outlineViewDataSource:
- (id)outlineView:(NSOutlineView *)outlineView child:(NSInteger)index ofItem:(id)item {
if([item isKindOfClass:[IFChildNode class]]) {
return nil;
}
return (item == nil ? [rootNode childAtIndex:index] : [(IFParentNode *)item childAtIndex:index]);
}
- (BOOL)outlineView:(NSOutlineView *)outlineView isItemExpandable:(id)item {
return (item == nil || [item isKindOfClass:[IFParentNode class]]);
}
- (NSInteger)outlineView:(NSOutlineView *)outlineView numberOfChildrenOfItem:(id)item {
if([item isKindOfClass:[IFChildNode class]]) {
return 0;
}
return (item == nil ? [rootNode numberOfChildren] : [(IFParentNode *)item numberOfChildren]);
}
- (id)outlineView:(NSOutlineView *)outlineView objectValueForTableColumn:(NSTableColumn *)tableColumn byItem:(id)item {
if([item isKindOfClass:[IFChildNode class]]) {
return ((IFChildNode *)item).title;
}
if([item isKindOfClass:[IFParentNode class]]) {
return ((IFParentNode *)item).title;
}
return nil;
}
// Unessential methods for datasource
- (BOOL)outlineView:(NSOutlineView *)outlineView isGroupItem:(id)item {
return (item == nil || [item isKindOfClass:[IFParentNode class]]);
}
- (BOOL)outlineView:(NSOutlineView *)outlineView shouldSelectItem:(id)item {
return ([item isKindOfClass:[IFChildNode class]]);
}
/* - - - - - - - - - - - - - - - - - - - -
IfChild
- - - - - - - - - - - - - - - - - - - - */
@implementation IFChildNode
@synthesize title;
- (id)initWithTitle:(NSString *)theTitle {
if(self = [super init]) {
self.title = theTitle;
}
return self;
}
- (void)dealloc {
self.title = nil;
[super dealloc];
}
@end
/* - - - - - - - - - - - - - - - - - - - -
IfParent
- - - - - - - - - - - - - - - - - - - - */
@implementation IFParentNode
@synthesize title, children;
- (id)initWithTitle:(NSString *)theTitle children:(NSMutableArray *)theChildren {
if(self = [super init]) {
self.title = theTitle;
self.children = (theChildren == nil ? [NSMutableArray new] : theChildren);
}
return self;
}
- (void)addChild:(id)theChild {
[self.children addObject:theChild];
}
- (void)insertChild:(id)theChild atIndex:(NSUInteger)theIndex {
[self.children insertObject:theChild atIndex:theIndex];
}
- (void)removeChild:(id)theChild {
[self.children removeObject:theChild];
}
- (NSInteger)numberOfChildren {
return [self.children count];
}
- (id)childAtIndex:(NSUInteger)theIndex {
return [self.children objectAtIndex:theIndex];
}
- (void)dealloc {
self.title = nil;
self.children = nil;
[super dealloc];
}