7

Possible Duplicate:
How to wrap a Struct into NSObject
Can the new Clang Objective-C literals be redirected to custom classes?

I have a custom struct:

typedef struct {
    float f1;
    float f2;
} MYCustomStruct;

that I need to add to an NSArray. I've already written a category to create NSValues of these structs, which I then add to the NSArray, however I'd like to simplify that even further using boxed expressions, if possible. I'd love to be able to do this:

@[@(instanceOfMYCustomStruct)];

however, I'm confronted with the following error:

Illegal type 'MYCustomStruct' used in a boxed expression

Is there a way to use boxed expressions with custom structs?

Community
  • 1
  • 1
Patrick Perini
  • 22,555
  • 12
  • 59
  • 88
  • This question might answer your problem - http://stackoverflow.com/questions/11252392/can-the-new-clang-objective-c-literals-be-redirected-to-custom-classes – deanWombourne Oct 29 '12 at 16:29
  • 1
    See http://stackoverflow.com/questions/5691881/how-to-wrap-a-struct-into-nsobject – Jon Reid Oct 29 '12 at 16:31
  • Even if you could box it - how would you get it out? A simple cast wouldn't work, and you can't return an unknown type (unless it's a pointer) from a function in objc. – Richard J. Ross III Oct 29 '12 at 16:34

1 Answers1

4

I would use a NSValue to box a struct, as it has built-in support for it. Unfortunately, you cannot use objective-c's cool literals for it, though:

struct foo myStruct;
NSValue *val = [NSValue valueWithBytes:&myStruct objCType:@encode(typeof(myStruct))];

// to pull it out...
struct foo myStruct;
[val getValue:&myStruct];

While this may be unwieldy & ugly amidst other objc code, you have to ask yourself - why are you using a struct in the first place in Objective-C? There are few speed performances gained over using an object with a few @property(s), the only real reason I could see is if you are integrating with a C library for compatibility with memory layouts, and even then, the structure of an objective-c object's memory layout is well-defined, so long as the superclass doesn't change.

So what is your real purpose in boxing a struct? If we have that, we can help you further.

Richard J. Ross III
  • 55,009
  • 24
  • 135
  • 201
  • If you use Objective-C++ you could define an overloaded Box() function that takes in your struct and returns an NSValue. Or just name the function B() for brevity and doesn't need more characters than Objective-C's boxing syntactic sugar. – adib Oct 30 '12 at 04:28
  • With Objective-C++ you could also define an `operator NSValue*(const struct myStruct*)` that converts it seamlessly. – adib Oct 30 '12 at 04:29
  • @adib true, and in some situations that may be acceptable, but that does mean that the struct is no longer a POD. – Richard J. Ross III Oct 30 '12 at 04:35
  • The `struct` can still be a plain sequence of bytes -- just define the `operator` as a freestanding function (instead of a member function). – adib Oct 31 '12 at 03:17
  • There totally should be a NSValue boxing literal syntax on Clang. Maybe I'll write a patch... – paulotorrens Jun 07 '15 at 15:49
  • 1
    typedef struct __attribute__((objc_boxable)) { float f1; } myType; myType a; NSValue *val = @(a); – user2423351 Jun 30 '17 at 10:29
  • 1
    @paulotorrens use __attribute__((objc_boxable)) – user2423351 Jun 30 '17 at 10:40