3

In connecting my C++ data model to my Cocoa table column UI, I'm wondering if I can provide the a C++ class instance at the id (identifier) to initWithIdentifier

// what magic needs to occur to create an id from a CPP class?
id someIDMadeFromAClassInstance = a_ptr_to_a_cpp_class_instance;

NSTableColumn *col = [[NSTableColumn alloc] initWithIdentifier:someIDMadeFromAClassInstance"];

The whole point of this is so that when the NSTable's datasource method objectValueForTableColumn gets called, I can retrieve the id and somehow convert if back to a valid C++ class instance:

id columnIdentifer = [aTableColumn identifier];

MyCPPClass* pAValidClass = [someMagicOnTheID columnIdentifer];

pAValidClass->AClassMethod();

I'm guessing there's a more traditional method of doing this, but I wanted to simplify the connection between the Cocoa UI and a pure C++ model.

SMGreenfield
  • 1,680
  • 19
  • 35

1 Answers1

4

A C++ object pointer cannot be stored in an id type variable. In Objective-C, id is a pointer to an Objective-C object of unknown type. Since a C++ object is not an Objective-C object, it is not safe to store the pointer to a C++ object in an id.

The solution is to add a property to your Objective-C class that will store a C++ object pointer. If you must use an id, you could make an Objective-C class that wraps a property that stores the C++ object pointer, for example:

@interface MyCPPClassWrapper : NSObject

@property (nonatomic, assign) MyCPPClass *myCPPClass;

@end

// ...

MyCPPClassWrapper *wrapper = [[MyCPPClassWrapper alloc] initWithMyCPPClass:myCPPClass];

// Hand wrapper off to your NSTable

Take a look at NSValue as well. It provides a storage mechanism for C-style pointers. For NSValue, you could do something like this:

NSValue *someIDMadeFromAClassInstance = [NSValue valueWithPointer:a_ptr_to_a_cpp_class_instance];

NSTableColumn *col = [[NSTableColumn alloc] initWithIdentifier:someIDMadeFromAClassInstance"];

// ...

NSValue *columnIdentifer = (NSValue *)[aTableColumn identifier];
MyCPPClass* pAValidClass = (MyCPPClass *)[columnIdentifer pointerValue];
pAValidClass->AClassMethod();
aust
  • 914
  • 4
  • 12
  • NSValue won't call special methods on the C++ object properly. – newacct Nov 19 '13 at 11:14
  • NSValue would act as a weak_ptr (without the safety of offering methods such as expired) since it's a wrapper acting as a bridge between C++ Pointer land to Objective-C Pointer land in this case. I highly suggest using my first option as that gives the programmer control and the ability to add special methods to determine if the pointer is invalid (expired) or not. – aust Nov 19 '13 at 15:19