2009-08-21 38 views
0

我正在构建我的应用程序后添加一些代码,但我得到的Un-Recongnized选择器发送到实例错误停止我的应用程序运行。下面是错误的图片 -未识别的选择器已发送到实例错误

alt text http://www.grabup.com/uploads/20f66eecee4bd96198c7bbcfe647ec74.png?direct

这是我添加的代码(这是一个NSOutlineView的数据源)

- (id)init 
{ 
    self = [super init]; 
    if (self != nil) { 
     // initialization code, rootsObjects is a NSArray instance variable 
     rootObjects = [NSArray arrayWithObjects:@"Joshua", @"Erne", nil]; 
    } 
    return self; 
} 

// here NSOutlineView asks how many children rows to display for a given item 
- (int)outlineView:(NSOutlineView *)outlineView numberOfChildrenOfItem:(id)item 
{ 
    // if item is nil this should be a Root row, else I pass 0 for example but should be the count of objects contained in item 
    return (item == nil) ? [rootObjects count] : 0; 
} 

// here NSOutlineView asks if a given item can be expanded i.e contains children 
- (BOOL)outlineView:(NSOutlineView *)outlineView isItemExpandable:(id)item 
{ 
    // again I return YES for example, but should be based on the count of objects contained in item 
    return YES; //(item == nil) ? YES : ([item numberOfChildren] != -1); 
} 

// here NSOutlineView asks for the object (some treelike structure) assigned to the nth index child row of item 
- (id)outlineView:(NSOutlineView *)outlineView 
      child:(int)index 
      ofItem:(id)item 
{ 
    // if item is nil I opass the appropriate Root row, else I pass nil for example but should be an object contained in item 
    return (item == nil) ? [rootObjects objectAtIndex:index] : nil; 
} 

// here NSOutlineView asks for the objectValue (usually a NSString)) to be displayed in tableColumn for the given item 
- (id)outlineView:(NSOutlineView *)outlineView 
objectValueForTableColumn:(NSTableColumn *)tableColumn 
      byItem:(id)item 
{ 
    // pass the object we want to display in the tableColumn for item 
    return item ; 
    // here I pass item for example since I know it's a NSString, but usually will be something to compute. 
    // the [tableColumn identifier] property (that can be set in Interface Builder) is very useful here. 
} 

// here NSOutlineView asks for the NSCell to be used by tableColumn for the given item 
- (NSCell *)outlineView:(NSOutlineView *)ov 
dataCellForTableColumn:(NSTableColumn *)tableColumn 
        item:(id)item 
{ 
    // the nil tableColumn represents the unified root row style 
    if (tableColumn == nil) { 
     // pass a cell we want to be used as root row (assume we've have assigned "Name" as identifier of some tableColumn) 
     return [[treeTable tableColumnWithIdentifier:@"Name"] dataCell]; 
    } 
    // else just pass the default cell 
    return [tableColumn dataCellForRow:[treeTable rowForItem:item]]; 
} 

- (BOOL)outlineView:(NSOutlineView *)outlineView isGroupItem:(id)item { 
    return YES; 
} 

这里是代码我在同一个文件(数据源)作为上面的代码。

- (void)awakeFromNib { 

    dragType = [NSArray arrayWithObjects: @"factorialDragType", nil]; 

    [ dragType retain ]; 

    [ treeTable registerForDraggedTypes:dragType ]; 
    NSSortDescriptor* sortDesc = [[NSSortDescriptor alloc] initWithKey:@"position" ascending:YES]; 
    [groupTreeControl setSortDescriptors:[NSArray arrayWithObject: sortDesc]]; 
    [ sortDesc release ]; 
} 


//------------------------------------ 
#pragma mark NSOutlineView datasource methods -- see NSOutlineViewDataSource 
//--------------------------------------------------------------------------- 
- (BOOL) outlineView : (NSOutlineView *) outlineView 
      writeItems : (NSArray*) items 
     toPasteboard : (NSPasteboard*) pboard { 

    [ pboard declareTypes:dragType owner:self ];   
    // items is an array of _NSArrayControllerTreeNode see http://theocacao.com/document.page/130 for more info 
    draggedNode = [ items objectAtIndex:0 ]; 

    return YES; 
} 




- (BOOL)outlineView:(NSOutlineView *)outlineView acceptDrop:(id <NSDraggingInfo>)info item:(id)item childIndex:(int)index { 

    _NSArrayControllerTreeNode* parentNode = item; 
    _NSArrayControllerTreeNode* siblingNode; 
    _NSControllerTreeProxy* proxy = [ groupTreeControl arrangedObjects ]; 

    NSManagedObject* draggedGroup = [ draggedNode observedObject ]; 

    BOOL draggingDown = NO; 
    BOOL isRootLevelDrag = NO; 

    // ---------------------- 
    // Setup comparison paths 
    // ------------------------- 
    NSIndexPath* draggedPath = [ draggedNode indexPath ]; 
    NSIndexPath* siblingPath = [ NSIndexPath indexPathWithIndex: index ]; 
    if (parentNode == NULL) {  
     isRootLevelDrag = YES; 
    } else { 
     // A non-root drag - the index value is relative to this parent's children 
     siblingPath = [ [ parentNode indexPath ] indexPathByAddingIndex: index ]; 
    } 

    // ---------------------- 
    // Compare paths - modify sibling path for down drags, exit for redundant drags 
    // -----------------------------------------------------------------------------  
    switch ([ draggedPath compare:siblingPath]) { 
     case NSOrderedAscending: // reset path for down dragging 
      if (isRootLevelDrag) { 
       siblingPath = [ NSIndexPath indexPathWithIndex: index - 1];        
      } else { 
       siblingPath = [ [ parentNode indexPath ] indexPathByAddingIndex: index - 1 ]; 
      } 
      draggingDown = YES; 
      break; 

     case NSOrderedSame: 
      return NO; 
      break;    
    } 

    siblingNode = [ proxy nodeAtIndexPath:siblingPath ];  

    // NSLog(@"returning early"); 
    // return NO; // TODO robustify 


    // ------------------------------------------------------------ 
    // SPECIAL CASE: Dragging to the bottom 
    // ------------------------------------------------------------ 
    // - K        - K       - C        - C 
    // - - U        - - C  OR  - U        - F 
    // - - C  ====>  - - F     - F        - K 
    // - - F    - U    - K        - U 
    // ------------------------------------------------------------ 
    if (isRootLevelDrag && siblingNode == NULL) {   
     draggingDown = YES; 
     siblingPath = [ NSIndexPath indexPathWithIndex: [ proxy count ] - 1 ];   
     siblingNode = [ proxy nodeAtIndexPath:siblingPath ] ; 
    } 

    // ------------------------------------------------------------ 
    // Give the dragged item a position relative to it's new sibling 
    // ------------------------------------------------------------ 
    NSManagedObject* sibling = [ siblingNode observedObject ]; 
    NSNumber* bystanderPosition = [ sibling valueForKey:@"position"]; 
    int newPos = (draggingDown ? [ bystanderPosition intValue ] + 1 : [ bystanderPosition intValue ] - 1); 
    [draggedGroup setValue:[ NSNumber numberWithInt:newPos ] forKey:@"position"]; 

    // ---------------------------------------------------------------------------------------------- 
    // Set the new parent for the dragged item, resort the position attributes and refresh the tree 
    // ----------------------------------------------------------------------------------------------  
    [ draggedGroup setValue:[ parentNode observedObject ] forKey:@"parent" ]; 
    [ self resortGroups:[draggedGroup managedObjectContext] forParent:[ parentNode observedObject ] ];   
    [ groupTreeControl rearrangeObjects ]; 
    return YES;    
} 






- (NSArray*) getSubGroups:(NSManagedObjectContext*)objectContext forParent:(NSManagedObject*)parent { 
    NSFetchRequest *request = [[[NSFetchRequest alloc] init] autorelease]; 
    NSEntityDescription *entity = [NSEntityDescription entityForName:@"projects" inManagedObjectContext:objectContext]; 

    [request setEntity:entity]; 
    NSSortDescriptor* aSortDesc = [[NSSortDescriptor alloc] initWithKey:@"position" ascending:YES]; 
    [request setSortDescriptors:[NSArray arrayWithObject: aSortDesc] ]; 
    [aSortDesc release]; 

    NSPredicate* validationPredicate = [NSPredicate predicateWithFormat:@"parent == %@", parent ]; 

    [ request setPredicate:validationPredicate ]; 

    NSError *error = nil; // TODO - check the error bozo 
    return [objectContext executeFetchRequest:request error:&error];  
} 




- (void) resortGroups:(NSManagedObjectContext*)objectContext forParent:(NSManagedObject*)parent { 

    NSArray *array = [ self getSubGroups:objectContext forParent:parent ]; 

    // Reset the indexes... 
    NSEnumerator *enumerator = [array objectEnumerator]; 
    NSManagedObject* anObject; 
    int index = 0; 
    while (anObject = [enumerator nextObject]) { 
     // Multiply index by 10 to make dragging code easier to implement ;) .... 
     [anObject setValue:[ NSNumber numberWithInt:(index * INTERVAL) ] forKey:@"position"];  
     index++; 
    } 


} 

- (NSDragOperation)outlineView:(NSOutlineView *)outlineView validateDrop:(id <NSDraggingInfo>)info proposedItem:(id)item proposedChildIndex:(int)index { 

    _NSArrayControllerTreeNode* newParent = item; 

    // drags to the root are always acceptable 
    if (newParent == NULL) { 
     return NSDragOperationGeneric; 
    } 

    // Verify that we are not dragging a parent to one of it's ancestors 
    // causes a parent loop where a group of nodes point to each other and disappear 
    // from the control 
    NSManagedObject* dragged = [ draggedNode observedObject ];  
    NSManagedObject* newP = [ newParent observedObject ]; 

    if ([ self category:dragged isSubCategoryOf:newP ]) { 
     return NO; 
    }  

    return NSDragOperationGeneric; 
} 

- (BOOL) category:(NSManagedObject*)cat isSubCategoryOf:(NSManagedObject*) possibleSub { 

    // Depends on your interpretation of subCategory .... 
    if (cat == possibleSub) { return YES; } 

    NSManagedObject* possSubParent = [possibleSub valueForKey:@"parent"]; 

    if (possSubParent == NULL) { return NO; } 

    while (possSubParent != NULL) {  
     if (possSubParent == cat) { return YES; } 

     // move up the tree 
     possSubParent = [possSubParent valueForKey:@"parent"];   
    } 

    return NO; 
} 

// This method gets called by the framework but the values from bindings are used instead 
+0

我不确定您提供的信息是否足够...您是否也可以添加堆栈跟踪? – fbrereto 2009-08-21 16:41:26

+0

调试器中的错误没有提供堆栈跟踪。我还能找到它吗? – Joshua 2009-08-21 16:44:44

+0

在调试器控制台中,输入“b objc \ _exception \ _throw”(或使用异常窗口Run-> Show-> Breakpoints添加异常)。当调试器中断时,打开调试器窗口(Run-> Debugger)。左上方的面板将显示堆栈跟踪。在stach trace的某处,你会看到一条-copy消息;在黑色下的第一个条目是你的代码触发问题的关键。 – 2009-08-21 16:52:15

回答

1

该错误应提供收到无法识别的方法和发送的无法识别的方法的类的名称。 (1)如果你认识到方法名称 - 如果你已经写了一行调用该方法的代码 - 检查代码行并确保该方法的目标调用是有效的,是正确的类型,并没有被释放到其他地方。

通常情况下,当您在某处过度释放某个对象并且某个新类型的对象占用了旧对象的内存时,会导致无法识别的方法调用错误。 (2)如果你没有写出对该方法的调用,那么你有其他的提供了错误类型的对象给一些框架方法,或者,你已经过度发布了一些东西。

如果你怀疑过度释放,打开NSZombies或使用仪器中的僵尸跟踪功能(是的,彼得说什么)。因此,错误是NSTreeControllerTreeNode ... doesn't respond to -copyWithZone:

几乎可以保证,表明您已经尝试将树控制器树节点推送到字典的某处作为关键字,并且字典正试图将其复制。至少,这是最典型的情况。

这仍然可能是一个过度释放问题,其中NSTreeControllerTreeNode的一个实例恰好位于NSString曾经存在的内存中。

搜索NSZombie的Xcode文档,以获取有关在当前版本的开发工具中将其打开的更多信息。

+0

我认为它必须是第2号。当我去“运行性能工具”菜单没有僵尸选项,你可以看到这里 - http://www.grabup.com/uploads/56e2b7a108333326d1acc6bfdde7d064.png?direct – Joshua 2009-08-21 17:51:15

+0

那么,可能有一个僵尸模板一些假设的未来版本的Xcode,但没有在3.1.3中。 ☺ – 2009-08-21 22:19:00

+0

我还注意到的是,如果我摆脱了第一个问题的代码,应用程序运行正常,没有问题。所以问题必须在代码中的某处。 – Joshua 2009-08-22 06:55:10

0

NSTreeControllerTreeNode不是标准的可可类。

您的意思是使用NSTreeController还是NSTreeNode

+0

就是这样,我没有真正使用它。我注意到当我摆脱代码(第一篇文章中的代码)时,应用程序运行顺畅,所以问题必须在第一篇文章的代码中。我没有在那里使用NSTreeControllerTreeNode。 – Joshua 2009-08-22 11:33:15

+0

“第一篇文章中的代码”是什么意思? – Abizern 2009-08-22 12:15:04

+0

我的意思是,问题中的代码。 – Joshua 2009-08-22 13:23:44

相关问题