我在添加一些代码后构建我的应用程序,但是我发送了Un-Recongnized Selector发送到实例错误阻止我的应用程序运行。这是错误的图片 -
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 :(得分:1)
错误应该提供接收到无法识别的方法的类的名称以及发送的无法识别的方法。
(1)如果您识别方法名称 - 如果您编写了一行(或多行)调用该方法的代码 - 请查看代码行并确保方法调用的目标是有效的,是正确的类型,并没有在其他地方过度释放。
通常,当您在某处过度释放对象并且错误类型的新对象占用旧对象的内存时,会导致无法识别的方法调用错误。
(2)如果你没有写一个对该方法的调用,那么你有其他人为某种框架方法提供了错误类型的对象,或者你又过度释放了一些东西。
如果您怀疑过度释放,请打开NSZombies或使用乐器中的Zombie追踪功能(是的,Peter说的话)。
所以,错误是NSTreeControllerTreeNode ... doesn't respond to -copyWithZone:
。
几乎可以保证表明您已尝试将树控制器树节点作为键移动到某个字典中,而字典正在尝试复制它。至少,这是最典型的情况。
这仍然可能是一个过度释放的问题,其中NSTreeControllerTreeNode的一个实例恰好位于NSString曾经存在的内存中。
在xcode文档中搜索NSZombie
,了解有关在当前版本的开发工具中启用它的详细信息。
答案 1 :(得分:0)
NSTreeControllerTreeNode
不是标准的Cocoa类。
您的意思是使用NSTreeController
还是NSTreeNode
?