Created
January 15, 2019 13:14
-
-
Save jidolstar/606b6a6d5aa7f7377d94d22d163d91f3 to your computer and use it in GitHub Desktop.
bsReflection : objective-c
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> | |
| //Reflection | |
| @interface bsReflection : NSObject | |
| +(NSString*)stringFromClass:(Class)clazz; //ํด๋์ค๋ก๋ถํฐ ํด๋์ค ์ด๋ฆ์ ๊ฐ์ ธ์จ๋ค. | |
| +(Class)classFromString:(NSString*)className; //ํด๋์ค ์ด๋ฆ์ผ๋ก๋ถํฐ ํด๋์ค๋ฅผ ๊ฐ์ ธ์จ๋ค. | |
| +(Class)classFromObject:(id)object; //๊ฐ์ฒด๋ก๋ถํฐ ํด๋์ค๋ฅผ ๊ฐ์ ธ์จ๋ค. | |
| +(NSString*)classNameFromObject:(id)object; //๊ฐ์ฒด๋ก๋ถํฐ ํด๋์ค ์ด๋ฆ์ ๊ฐ์ ธ์จ๋ค. | |
| +(Class)getPropClassOfObject:(id)object key:(NSString*)key; //๊ฐ์ฒด์ ํ๋กํผํฐ์ ํด๋์ค๋ฅผ ๊ฐ์ ธ์จ๋ค. | |
| +(Class)getPropClassOfClass:(Class)clazz key:(NSString*)key; //ํด๋์ค์ ํ๋กํผํฐ์ ํด๋์ค๋ฅผ ๊ฐ์ ธ์จ๋ค. | |
| +(Class)getPropClassOfRootObject:(id)object keyPath:(NSString*)keyPath; //๊ธฐ๋ฐ๊ฐ์ฒด๋ก๋ถํฐ keyPath์ ํด๋นํ๋ ์์ฑ์ ํด๋์ค๋ฅผ ์ป์ด์จ๋ค. | |
| +(Class)getPropClassOfRootClass:(Class)clazz keyPath:(NSString*)keyPath; //๊ธฐ๋ฐํด๋์ค๋ก๋ถํฐ keyPath์ ํด๋นํ๋ ์์ฑ์ ํด๋์ค๋ฅผ ์ป์ด์จ๋ค. | |
| +(NSArray*)getPropNamesOfClass:(Class)clazz superInquiry:(BOOL)superInquiry; //ํด๋์ค์ ํ๋กํผํฐ ์ด๋ฆ์ ๋ฐฐ์ด๋ก ๊ฐ์ ธ์จ๋ค. superInquiry๋ ํด๋นํด๋์ค์ ๋ถ๋ชจํด๋์ค ํ๋กํผํฐ๋ ํ์ํ ๊ฒ์ธ์ง ๊ฒฐ์ ํ๋ ํ๋๊ทธ๋ค. | |
| +(id)getPropValueOfObject:(id)object keyPath:(NSString*)keyPath; //๊ฐ์ฒด์์ ์ฃผ์ด์ง ์ด๋ฆ์ ๊ฐ์ง ํ๋กํผํฐ์ ๊ฐ์ ๊ฐ์ ธ์จ๋ค. | |
| +(void)setPropValueOfObject:(id)object keyPath:(NSString*)keyPath value:(id)value; //๊ฐ์ฒด์์ ์ฃผ์ด์ง ์ด๋ฆ์ ๊ฐ์ง ํ๋กํผํฐ์ ๊ฐ์ ์ ํ ํ๋ค.(KVO, KVC์ ์ ์ฉ์๋จ) | |
| +(BOOL)hasPropAtObject:(id)object keyPath:(NSString*)keyPath; //๊ฐ์ฒด์์ ์ฃผ์ด์ง ์ด๋ฆ์ ํ๋กํผํฐ๋ฅผ ๊ฐ์ง๊ณ ์๋๊ฐ? | |
| +(BOOL)hasPropAtClass:(Class)clazz keyPath:(NSString*)keyPath; //ํด๋์ค์์ ์ฃผ์ด์ง ์ด๋ฆ์ ํ๋กํผํฐ๋ฅผ ๊ฐ์ง๊ณ ์๋๊ฐ? | |
| @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 "bsReflection.h" | |
| #import <objc/runtime.h> | |
| #import <objc/message.h> | |
| #import "bs.h" | |
| @implementation bsReflection | |
| //ํด๋์ค๋ก๋ถํฐ ํด๋์ค ์ด๋ฆ์ ๊ฐ์ ธ์จ๋ค. | |
| +(NSString*)stringFromClass:(Class)clazz { | |
| return NSStringFromClass( clazz ); | |
| } | |
| //ํด๋์ค ์ด๋ฆ์ผ๋ก๋ถํฐ ํด๋์ค๋ฅผ ๊ฐ์ ธ์จ๋ค. | |
| +(Class)classFromString:(NSString*)className { | |
| return NSClassFromString( className ); | |
| } | |
| //๊ฐ์ฒด๋ก๋ถํฐ ํด๋์ค๋ฅผ ๊ฐ์ ธ์จ๋ค. | |
| +(Class)classFromObject:(id)object { | |
| return [object class]; | |
| } | |
| //๊ฐ์ฒด๋ก๋ถํฐ ํด๋์ค ์ด๋ฆ์ ๊ฐ์ ธ์จ๋ค. | |
| +(NSString*)classNameFromObject:(id)object { | |
| return NSStringFromClass( [object class] ); | |
| } | |
| //๊ฐ์ฒด์ ํ๋กํผํฐ์ ํด๋์ค๋ฅผ ๊ฐ์ ธ์จ๋ค. | |
| +(Class)getPropClassOfObject:(id)object key:(NSString*)key { | |
| return [self getPropClassOfClass:[object class] key:key]; | |
| } | |
| //ํด๋์ค์ ํ๋กํผํฐ์ ํด๋์ค๋ฅผ ๊ฐ์ ธ์จ๋ค. | |
| +(Class)getPropClassOfClass:(Class)clazz key:(NSString*)key { | |
| const char *nm = [key UTF8String]; | |
| objc_property_t p0 = class_getProperty( clazz, nm ); | |
| if( p0 == NULL ) { | |
| return NULL; | |
| } | |
| NSString *attr = [NSString stringWithFormat:@"%s", property_getAttributes( p0 )]; | |
| NSArray *attrSplit = [attr componentsSeparatedByString:@"\""]; //"T@"NSString",R,V_test"์์ NSString๋ง ์ถ์ถํด์ผ ํ๋ค. | |
| NSString *className = nil; | |
| if ([attrSplit count] >= 2) { | |
| className = [attrSplit objectAtIndex:1]; | |
| } | |
| if( className == nil ) return NULL; | |
| return NSClassFromString( className ); | |
| } | |
| //๊ธฐ๋ฐ๊ฐ์ฒด๋ก๋ถํฐ keyPath์ ํด๋นํ๋ ์์ฑ์ ํด๋์ค๋ฅผ ์ป์ด์จ๋ค. | |
| +(Class)getPropClassOfRootObject:(id)object keyPath:(NSString*)keyPath { | |
| return [self getPropClassOfRootClass:[object class] keyPath:keyPath]; | |
| } | |
| //๊ธฐ๋ฐํด๋์ค๋ก๋ถํฐ keyPath์ ํด๋นํ๋ ์์ฑ์ ํด๋์ค๋ฅผ ์ป์ด์จ๋ค. | |
| +(Class)getPropClassOfRootClass:(Class)clazz keyPath:(NSString*)keyPath { | |
| NSArray *names = [bs strSplit:keyPath seperator:@"." trim:NO]; | |
| if( [names count] == 0 ) return NULL; | |
| __block Class c = clazz; | |
| [names enumerateObjectsUsingBlock:^(NSString *nm, NSUInteger idx, BOOL *stop) { | |
| objc_property_t p = class_getProperty(c, [nm UTF8String]); | |
| if( !p ) { | |
| *stop = YES; | |
| return; | |
| } | |
| NSString *attr = [NSString stringWithFormat:@"%s", property_getAttributes( p )]; | |
| NSArray *attrSplit = [attr componentsSeparatedByString:@"\""]; | |
| if ( [attrSplit count] < 2) { | |
| *stop = YES; | |
| c = NULL; | |
| } | |
| NSString *className = [attrSplit objectAtIndex:1]; | |
| c = NSClassFromString( className ); | |
| }]; | |
| return c; | |
| } | |
| //ํด๋์ค์ ํ๋กํผํฐ ์ด๋ฆ์ ๋ฐฐ์ด๋ก ๊ฐ์ ธ์จ๋ค. superInquiry๋ ํด๋นํด๋์ค์ ๋ถ๋ชจํด๋์ค ํ๋กํผํฐ๋ ํ์ํ ๊ฒ์ธ์ง ๊ฒฐ์ ํ๋ ํ๋๊ทธ๋ค. | |
| +(NSArray*)getPropNamesOfClass:(Class)clazz superInquiry:(BOOL)superInquiry{ | |
| if( clazz == NULL || clazz == [NSObject class] ) { | |
| return nil; | |
| } | |
| NSMutableArray *r = [[NSMutableArray alloc] init]; | |
| unsigned int count, i; | |
| objc_property_t *ps = class_copyPropertyList( clazz, &count ); | |
| for( i = 0; i < count; i++ ) { | |
| objc_property_t p = ps[i]; | |
| const char *pn = property_getName( p ); | |
| if( pn ) { | |
| [r addObject:[NSString stringWithUTF8String:pn]]; | |
| } | |
| } | |
| free( ps ); | |
| if( superInquiry ) { | |
| NSArray *sr = [self getPropNamesOfClass:[clazz superclass] superInquiry:YES]; | |
| if( sr != nil ) [r addObjectsFromArray:sr]; | |
| } | |
| return [NSArray arrayWithArray:r]; | |
| } | |
| //๊ฐ์ฒด์์ ์ฃผ์ด์ง ์ด๋ฆ์ ๊ฐ์ง ํ๋กํผํฐ์ ๊ฐ์ ๊ฐ์ ธ์จ๋ค. | |
| +(id)getPropValueOfObject:(id)object keyPath:(NSString*)keyPath { | |
| NSArray *t0 = [bs strSplit:keyPath seperator:@"." trim:NO]; | |
| if( [t0 count] > 0 ) { | |
| __block id t00 = object; | |
| [t0 enumerateObjectsUsingBlock:^(NSString *name, NSUInteger idx, BOOL *stop) { | |
| Ivar ivar = class_getInstanceVariable([t00 class], [[NSString stringWithFormat:@"_%@", name] UTF8String]); | |
| t00 = object_getIvar( t00, ivar ); | |
| if( t00 == nil ) *stop = YES; | |
| }]; | |
| return t00; | |
| } | |
| return nil; | |
| } | |
| //๊ฐ์ฒด์์ ์ฃผ์ด์ง ์ด๋ฆ์ ๊ฐ์ง ํ๋กํผํฐ์ ๊ฐ์ ์ ํ ํ๋ค.(KVO, KVC์ ์ ์ฉ์๋จ) | |
| +(void)setPropValueOfObject:(id)object keyPath:(NSString*)keyPath value:(id)value { | |
| NSArray *t0 = [bs strSplit:keyPath seperator:@"." trim:NO]; | |
| if( [t0 count] > 0 ) { | |
| id t00 = object; | |
| Ivar ivar = nil; | |
| long i = 0, j = [t0 count]; | |
| while( 1 ) { | |
| ivar = class_getInstanceVariable([t00 class], [[NSString stringWithFormat:@"_%@", t0[i]] UTF8String]); | |
| if( ++i < j ) { | |
| t00 = object_getIvar( t00, ivar ); | |
| if( t00 == nil ) break; | |
| } else { | |
| break; | |
| } | |
| } | |
| object_setIvar( t00, ivar, value ); | |
| } | |
| } | |
| //๊ฐ์ฒด์์ ์ฃผ์ด์ง ์ด๋ฆ์ ํ๋กํผํฐ๋ฅผ ๊ฐ์ง๊ณ ์๋๊ฐ? | |
| +(BOOL)hasPropAtObject:(id)object keyPath:(NSString*)keyPath { | |
| return [self hasPropAtClass:[object class] keyPath:keyPath]; | |
| } | |
| //ํด๋์ค์์ ์ฃผ์ด์ง ์ด๋ฆ์ ํ๋กํผํฐ๋ฅผ ๊ฐ์ง๊ณ ์๋๊ฐ? | |
| +(BOOL)hasPropAtClass:(Class)clazz keyPath:(NSString*)keyPath { | |
| //clazz์ name์ผ๋ก ์บ์ฑํ์! | |
| NSArray *names = [bs strSplit:keyPath seperator:@"." trim:NO]; | |
| if( [names count] == 0 ) return NO; | |
| __block Class c = clazz; | |
| __block BOOL has = NO; | |
| NSUInteger maxIdx = [names count] - 1; | |
| [names enumerateObjectsUsingBlock:^(NSString *nm, NSUInteger idx, BOOL *stop) { | |
| objc_property_t p = class_getProperty(c, [nm UTF8String]); | |
| if ( !p ) { | |
| has = NO; | |
| *stop = YES; | |
| return; | |
| } | |
| if( idx == maxIdx ) { | |
| has = YES; | |
| return; | |
| } | |
| NSString *attr = [NSString stringWithFormat:@"%s", property_getAttributes( p )]; | |
| NSArray *attrSplit = [attr componentsSeparatedByString:@"\""]; | |
| if ( [attrSplit count] < 2) { | |
| has = NO; | |
| *stop = YES; | |
| return; | |
| } | |
| NSString *className = [attrSplit objectAtIndex:1]; | |
| c = NSClassFromString( className ); | |
| }]; | |
| return has; | |
| } | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment