Reputation: 839
I would like to bind to Objective-C objects properties to each other, but the properties are c++ class. the property actually is a mathematical vector class, which is easier to work with since operator overload is quite useful with vector maths. (I dont even see a good way working with vector math with objective-C objects, isthere?)
The problem is that binding this vector property crashes the app. here is an example:
@interface M_Node : NSObject{
Vec3f pos;
M_Node *manipulator
}
@property Vec3f pos;
@end
@implementation
@synthesize pos;
@dynamic pos;
-(void)setPos:(Vec3f)newPos{
pos=Vec3f(newPos);
}
-(Vec3f)pos{
return Vec3f(pos);
}
- (id) init
{
self = [super init];
if (self != nil) {
[self bind:@"pos" toObject:self withKeyPath:@"manipulator.pos" options:nil];
}
return self;
}
the issue by Xcode: Atomic property of type 'Vec3f' (aka 'Vec3') synthesizing setter using non-trivial assignment operator
I use the Vec3f class from cinder: http://libcinder.org/docs/v0.8.3/classcinder_1_1_vec3.html
So the question is that how to bind c++ objects as properties in objective-c, or is it even possible? Is there another way to go? (In case you have any idea how to do clean vector, matrix etc. math in objective-c please let me know.)
This is what I found in the documentation:
KVC Conversion of Scalar and Structure Values The default implementations of the KVC methods valueForKey: and setValue:forKey: provide support for automatic object wrapping of scalar data types such as BOOL, char, double, float, int, and structures such as NSPoint, NSRange, and NSRect. When Cocoa scripting invokes valueForKey: to get a value, KVC automatically converts the value to an NSNumber object (for scalars) or NSValue object (for structures) if necessary. Similarly, setValue:forKey: determines the data type required by the appropriate accessor or instance variable for the specified key. If the data type is not an object, then the value is extracted from the passed object using the appropriate NSNumber orNSValue method. For more information, including a table of the supported types, see Scalar and Structure Support in Key-Value Coding Programming Guide
Still, there are wrappers for structs like NSRect. There might be a way to override the original valueForKey: so it could also handle Vec3f.
So this would be the new question: How to override the valueForKey: and setValue: forKey: so it would be able to handle my own c++ object?
Upvotes: 3
Views: 1935
Reputation: 90601
I very much doubt this will work.
Bindings is built on Key-Value Coding (KVC) and Key-Value Observing (KVO). You're using a key path of manipulator.pos
. That means that the manipulator
property must be an Objective-C object which is KVC- and KVO-compliant for the pos
property. It's not clear, but I suspect that M_Node
is a C++ class, not an Objective-C class, and therefore isn't KVC- or KVO-compliant for anything.
Next is the question of how KVC would return and pass the value of pos
if it could get to it. KVC will wrap non-object data types in NSNumber
or NSValue
to pass them around. However, if a Vec3f
is non-POD, then I doubt that will work well at all.
Ultimately, bindings isn't magic (although, admittedly, KVO has some near-magic isa-swizzling stuff in its implementation). The point is, would you expect that [[yourObject valueForKey:@"manipulator"] valueForKey:@"pos"]
would work? Would you expect [[yourObject valueForKey:@"manipulator"] setValue:someValue forKey:@"pos"]
to work? If not, then there's no chance bindings will work.
Upvotes: 1