NSOutlineView with C++ classes
NSOutlineView with C++ classes
- Subject: NSOutlineView with C++ classes
- From: Daniel Price <email@hidden>
- Date: Fri, 23 Sep 2005 13:58:31 +0100 (BST)
Hi, this is my first post here.
I use pure C++ for the core classes in my 3D app, and
ObjectiveC++ for the interface layer. This has worked
fine so far, but now I've hit a snag with the
NSOutlineView class which I plan to use for
manipulating objects in my hierarchical scene list. To
try and fix the problem, I threw together a little
sample app.
I have a C++ class, Group, which acts as both the
root, branch and leaf nodes in my hierarchy.
class Group{
public:
Group();
int noChildren();
void addNode(Group *g);
Group* getNode(int i);
bool isGroup();
string name;
protected:
vector<Group*> children;
};
This is very basic. The only data is the name
property, and a vector maintains pointers to the
children groups (if any). isGroup() returns true if
the object has any children. If I use this class in
the conventional way in place of NSObject-based
classes, it will fail because -
(id)outlineView:(NSOutlineView *)ov child:(int)index
ofItem:(id)item expects an object of type 'id' to be
returned. Casting Group to id or objc_object won't
work because the view (apparently) tries to talk to
the object returned as though it were an NSObject.
My 'solution' has been to use instances of an NSObject
based class, Wrapper in this function. Wrapper know's
nothing of C++; it just holds a pointer to the Group
class.
#import <Cocoa/Cocoa.h>
@class Group;
@interface Wrapper : NSObject {
id node;
}
-(void)setNode:(Group*)n;
-(id)node;
@end
#import "Wrapper.h"
@implementation Wrapper
-(void)setNode:(Group*)n {
node = n;
}
-(id)node {
return node;
}
@end
I can then pass Wrapper back as an id and all my code
works:
- (id)outlineView:(NSOutlineView *)ov child:(int)index
ofItem:(id)item {
if (item){
Group *s =((Group*)[itemnode])->getNode(index);
if (s)
{
Wrapper *w = [[Wrapper alloc] init];
[w setNode: s];
return w;
}
return nil;
}
Wrapper *w = [[Wrapper alloc] init];
// comment in this function to hide the root
[w setNode: root/*->getNode(index)*/];
return w;
}
To get the actual Group istance, I simply grab the
pointer from Wrapper:
- (id)outlineView:(NSOutlineView *)ov
objectValueForTableColumn:(NSTableColumn *)tableColumn
byItem:(id)item
{
if (item) {
NSString *s = [NSString stringWithCString:
((Group*)[item node])->name.c_str()];
return s;
}
}
And so on...
The problem, is this solution leaks memory. There's no
way to release each instance of Wrapper, and no-where
to set up an Autorelease pool. Does anyone have any
suggestions? Is there some other way of passing back
Group as an id without crashing the code?
Previously, I was using an NSTableView to display a
one-level scene and that worked fine because there was
no-need to pass back an id object. Apologies for the
long post.
___________________________________________________________
To help you stay safe and secure online, we've developed the all new Yahoo! Security Centre. http://uk.security.yahoo.com
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Cocoa-dev mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden