Skip to content

Commit

Permalink
add property query functions to NSObject category
Browse files Browse the repository at this point in the history
  • Loading branch information
Randy Becker committed Sep 24, 2010
1 parent 7f1ab69 commit f5f0d31
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 0 deletions.
4 changes: 4 additions & 0 deletions MARTNSObject.h
Expand Up @@ -3,6 +3,7 @@


@class RTIvar;
@class RTProperty;
@class RTMethod;
@class RTUnregisteredClass;

Expand All @@ -27,6 +28,9 @@
+ (NSArray *)rt_ivars;
+ (RTIvar *)rt_ivarForName: (NSString *)name;

+ (NSArray *)rt_properties;
+ (RTProperty *)rt_propertyForName: (NSString *)name;

// Apple likes to fiddle with -class to hide their dynamic subclasses
// e.g. KVO subclasses, so [obj class] can lie to you
// rt_class is a direct call to object_getClass (which in turn
Expand Down
20 changes: 20 additions & 0 deletions MARTNSObject.m
Expand Up @@ -4,6 +4,7 @@
#import <objc/runtime.h>

#import "RTIvar.h"
#import "RTProperty.h"
#import "RTMethod.h"
#import "RTUnregisteredClass.h"

Expand Down Expand Up @@ -123,6 +124,25 @@ + (RTIvar *)rt_ivarForName: (NSString *)name
return [RTIvar ivarWithObjCIvar: ivar];
}

+ (NSArray *)rt_properties
{
unsigned int count;
objc_property_t *list = class_copyPropertyList(self, &count);

NSMutableArray *array = [NSMutableArray array];
for(unsigned i = 0; i < count; i++)
[array addObject: [RTProperty propertyWithObjCProperty: list[i]]];

return array;
}

+ (RTProperty *)rt_propertyForName: (NSString *)name
{
objc_property_t property = class_getProperty(self, [name UTF8String]);
if(!property) return nil;
return [RTProperty propertyWithObjCProperty: property];
}

- (Class)rt_class
{
return object_getClass(self);
Expand Down
16 changes: 16 additions & 0 deletions main.m
Expand Up @@ -2,6 +2,7 @@

#import "MARTNSObject.h"
#import "RTIvar.h"
#import "RTProperty.h"
#import "RTMethod.h"
#import "RTUnregisteredClass.h"

Expand Down Expand Up @@ -157,8 +158,10 @@ @interface SampleClass : NSObject
{
id someIvar;
}
@property (assign, getter=customGetter) id someProperty;
@end
@implementation SampleClass
@synthesize someProperty=someIvar;
@end

static void TestIvarQuery(void)
Expand All @@ -172,6 +175,18 @@ static void TestIvarQuery(void)
TEST_ASSERT([ivar offset] == sizeof(id));
}

static void TestPropertyQuery(void)
{
NSArray *properties = [SampleClass rt_properties];
TEST_ASSERT([[properties valueForKey: @"name"] containsObject: @"someProperty"]);

RTProperty *property = [SampleClass rt_propertyForName: @"someProperty"];
TEST_ASSERT([[property name] isEqual: @"someProperty"]);
TEST_ASSERT([[property attributeEncodings] isEqual: @"GcustomGetter"]);
TEST_ASSERT([[property typeEncoding] isEqual: [NSString stringWithUTF8String: @encode(id)]]);
TEST_ASSERT([[property ivarName] isEqual: @"someIvar"]);
}

static void TestIvarAdd(void)
{
RTUnregisteredClass *unreg = [NSObject rt_createUnregisteredSubclassNamed: @"IvarAddTester"];
Expand Down Expand Up @@ -267,6 +282,7 @@ int main(int argc, char **argv)
TEST(TestMethodFetching);
TEST(TestSetMethod);
TEST(TestIvarQuery);
TEST(TestPropertyQuery);
TEST(TestIvarAdd);
TEST(TestEquality);
TEST(TestMessageSending);
Expand Down

0 comments on commit f5f0d31

Please sign in to comment.