Created
June 14, 2018 08:19
-
-
Save alexdrone/c26861714760897f0c997a8a2513205a to your computer and use it in GitHub Desktop.
ARC Struct Boxable Macros
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#import <Foundation/Foundation.h> | |
#define objc_struct_check(__TYPE__, __ACTION__) \ | |
[__ACTION__.identifier isEqualToString: @ #__TYPE__] \ | |
#define objc_struct_define \ | |
typedef struct __attribute__((objc_boxable)) \ | |
#define _objc_boxed_struct_make(__TYPE__, __ARGS__) \ | |
[[objc_boxed_struct alloc] initWithIdentifier:@ # __TYPE__ \ | |
andData:@(__ARGS__)]; \ | |
#define objc_boxed_struct_make(__STRUCT__) \ | |
_objc_boxed_struct_make(__typeof(__STRUCT__), __STRUCT__) \ | |
#define objc_struct_get(__TYPE__, __VAR__, __WRAPPER__) \ | |
__TYPE__ __VAR__; \ | |
assert(objc_struct_check(__TYPE__, __WRAPPER__)); \ | |
[__WRAPPER__.boxedStruct getValue:&__VAR__]; \ | |
NS_ASSUME_NONNULL_BEGIN | |
/// Wraps a dispatch action. | |
@interface objc_boxed_struct: NSObject | |
/// The struct identifier (automatically populated by @c objc_boxed_struct_make). | |
@property(nonatomic, readonly) NSString *identifier; | |
/// The boxed struct. | |
/// @note Use The @c objc_struct_check macro to check the action type and | |
/// @c objc_struct_get to unbox the arguments. | |
@property(nonatomic, readonly) NSValue *boxedStruct; | |
/// Don't use the initializer directly. | |
/// Use @c objc_boxed_struct_make to build a boxed struct. | |
- (instancetype)initWithIdentifier:(NSString *)identifier andData:(NSValue *)boxedStruct; | |
@end | |
NS_ASSUME_NONNULL_END |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#import "objc_struct.h" | |
@implementation objc_boxed_struct | |
- (instancetype)initWithIdentifier:(NSString *)identifier andData:(NSValue *)boxedStruct { | |
if (self = [super init]) { | |
_identifier = identifier; | |
_boxedStruct = boxedStruct; | |
} | |
return self; | |
} | |
@end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@interface test : XCTestCase | |
@end | |
objc_struct_define { | |
NSUInteger count; | |
NSString *name; | |
} MyAction1; | |
objc_struct_define { | |
NSNumber *number; | |
} MyAction2; | |
@implementation test | |
- (void)testMacros { | |
MyAction1 arg = { | |
.count = 0, | |
.name = @"" | |
}; | |
objc_boxed_struct *userInfo = objc_boxed_struct_make(arg); | |
if (objc_struct_check(MyAction2, userInfo)) { | |
XCTFail(); | |
} else if (objc_struct_check(MyAction1, userInfo)) { | |
objc_struct_get(MyAction1, arg2, userInfo); | |
XCTAssert(arg2.count == arg.count); | |
XCTAssert([arg2.name isEqualToString:arg.name]); | |
} | |
} | |
@end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment