objective-c - 无法识别的选择器发送到实例错误

标签 objective-c cocoa

我在添加一些代码后构建我的应用程序,但我收到无法识别的选择器发送到实例错误,导致我的应用程序无法运行。这是错误的图片 -

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

最佳答案

错误应提供接收无法识别的方法的类的名称以及发送的无法识别的方法。

(1) 如果您认识该方法名称——如果您编写了调用该方法的一行(或多行)代码——检查该代码行并确保该方法调用的目标有效,类型正确,并且没有在其他地方过度发布。

通常,当您在某处过度释放对象并且错误类型的新对象占据旧对象的内存时,会导致无法识别的方法调用错误。

(2) 如果您没有编写对该方法的调用,那么您向某些框架方法提供了错误类型的对象,或者您过度释放了某些内容。

如果您怀疑过度释放,请打开 NSZombies 或使用 Instruments 中的 Zombie 跟踪功能(是的,Peter 说的)。

所以,错误是NSTreeControllerTreeNode ...没有响应-copyWithZone:

几乎可以保证,这表明您已尝试将树 Controller 树节点作为键插入字典中的某个位置,并且字典正在尝试复制它。至少,这是最常见的情况。

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

在 Xcode 文档中搜索 NSZombie,了解有关在当前版本的开发工具中打开它的更多信息。

关于objective-c - 无法识别的选择器发送到实例错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1312874/

相关文章:

ios - 如何将自定义对象保存在数组中并将其存储在 NSUserDefaults - iPhone

iphone - 屏幕上 CALayers 的混合模式?那可能吗?

objective-c - 在 Cocoa 模拟浏览器中发出 HTTP 请求

objective-c - NSCollectionView 拖放 : Most Delegate Events Not Getting Called

xcode - 将窗口显示为模式的问题

ios - 如何获取 UICollectionView 中单元格的索引路径以获取特定内容偏移量?

ios - 不能调用带参数的类方法

objective-c - 从 .app 的包内容运行二进制文件

ios - 如何在小时和分钟上倒数计时器并在它为 0 时停止, objective-c

macos - 仅当自定义 TableRowView 类中的选择发生更改时才调用 drawSelectionInRect?