2009-08-21 43 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

相關問題