Created
January 11, 2012 14:52
-
-
Save BenedictC/1595008 to your computer and use it in GitHub Desktop.
Conceptually similar to a struct, but with object compatibility and memory management.
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
// | |
// Record.h | |
// | |
// Created by Benedict Cohen on 10/01/2012. | |
// Copyright (c) 2012 Benedict Cohen. All rights reserved. | |
// | |
// | |
/* | |
A Record is a Block (a.k.a. closure) that returns a struct. Unlike struct, Records handle memory management of their fields. | |
The fields can be Objective-C objects or basic C types. Because Records are Blocks they can be treated like objects. | |
To declare a Record you must define its fields and implement a function for creating an instance of the record. 2 types are | |
available once a record has been declare: | |
- A struct that contains the defined fields | |
- A block that takes zero arguments and returns a struct | |
Declaration example | |
=================== | |
//Person Record declaration | |
RECORD(Person, | |
RECORD_FIELD_OBJ(NSString *name) | |
RECORD_FIELD_PRM(float age) | |
); | |
////////The above declaration results in the follow code: | |
//Person | |
typedef struct Person_ | |
{ | |
__unsafe_unretained NSString *name; | |
float age; | |
} Person; | |
//PersonRecord | |
typedef Person(^PersonRecord)(void); | |
//////// | |
The creation function must return a Record. All object fields must be captured inside the returned block. | |
Creation function example | |
========================= | |
static PersonRecord createPersonRecord(NSString *name, float age) | |
{ | |
PersonRecord spartacus = ^(void) { | |
Person p; | |
p.name = name; | |
p.age = age; | |
return p; | |
}; | |
//for ARC code | |
return spartacus; | |
//for non-ARC code | |
//return (PersonRecord)[[spartacus copy] autorelease]; | |
} | |
Useage example | |
============== | |
PersonRecord bill = createPersonRecord(@"Bill Wyman", 75); | |
PersonRecord charlie = createPersonRecord(@"Charlie Wattts", 70); | |
PersonRecord keith = createPersonRecord(@"Keith Richards", 68); | |
PersonRecord mick = createPersonRecord(@"Mick Jagger", 68); | |
PersonRecord ronnie = createPersonRecord(@"Ronnie Wood", 64); | |
NSArray *stones = [NSArray arrayWithObjects: bill, charlie, keith, mick, ronnie, nil]; | |
for (PersonRecord stone in stones) | |
{ | |
Person p = stone(); | |
NSLog(@"%@ %f", p.name, p.age); | |
} | |
It's worth noting that the creation function has the potentinal to do interesting things. | |
*/ | |
#import <Foundation/Foundation.h> | |
#define RECORD_FIELD_OBJ(FIELD_TYPE_AND_NAME...) __unsafe_unretained FIELD_TYPE_AND_NAME; | |
#define RECORD_FIELD_PRM(FIELD_TYPE_AND_NAME...) FIELD_TYPE_AND_NAME; | |
#define RECORD(RECORD_NAME, FIELDS...) \ | |
\ | |
/*Typedef for struct returned by Record */ \ | |
typedef struct RECORD_NAME ## _ \ | |
{ \ | |
FIELDS \ | |
} RECORD_NAME; \ | |
\ | |
\ | |
\ | |
/*typedef of Record that returns struct*/ \ | |
typedef RECORD_NAME(^RECORD_NAME ## Record)(void); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment