Skip to content

Instantly share code, notes, and snippets.

@pyrtsa
Created January 10, 2013 18:36
Show Gist options
  • Save pyrtsa/4504593 to your computer and use it in GitHub Desktop.
Save pyrtsa/4504593 to your computer and use it in GitHub Desktop.
Boxing with Objective-C
// Public domain. (You're welcome.)
/// BOX(expr)
///
/// Macro. Box simple things like `CGPoint` or `CGRect` into an `NSValue`.
///
/// (Compare with the use of `@` in `@YES`, @123, @"abc" or `@(1 + 2)`.)
#define BOX(expr) ({ __typeof__(expr) _box_expr = (expr); \
[NSValue valueWithBytes:&_box_expr objCType:@encode(__typeof__(expr))]; })
// --- Example -----------------------------------------------------------------
CGPoint point = CGPointMake(10, 20);
CGSize size = CGSizeMake(30, 40);
CGRect rect = CGRectMake(10, 20, 30, 40);
UIEdgeInsets inset = UIEdgeInsetsMake(1, 2, 3, 4);
NSValue *pointValue = BOX(point); // = [NSValue valueWithCGPoint:point];
NSValue *sizeValue = BOX(size); // = [NSValue valueWithCGSize:size];
NSValue *rectValue = BOX(rect); // = [NSValue valueWithCGRect:rect];
NSValue *insetValue = BOX(inset); // = [NSValue valueWithUIEdgeInsets:inset];
// Boxed things can be put into an array.
NSArray *values1 = @[pointValue, sizeValue, rectValue, insetValue];
NSArray *values2 = @[BOX(point), BOX(size), BOX(rect), BOX(inset)];
// Works for temporaries as well.
NSValue *pointValueFromExpression = BOX(CGPointMake(10, 20));
// Practical for logging things with NSLog:
CGRect rect = CGRectMake(10, 20, 30, 40);
NSLog(@"rect: %@", BOX(rect)); // -> rect: NSRect: {{10, 20}, {30, 40}}
// --- But watch out, you can shoot yourself to the foot with this: ------------
NSValue *badValue = BOX(@[]); // ***Not even a warning!***
// Improvements to fix this, or any other issue are very welcome!
@pyrtsa
Copy link
Author

pyrtsa commented Jan 10, 2013

For the Objective-C++'ers out there, try out https://gist.github.com/539747 as well.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment