Created
August 13, 2017 15:32
-
-
Save YauzZ/d5a6bedeac6588454f5f57204416bd3a to your computer and use it in GitHub Desktop.
鸭子对象例子
This file contains 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
// | |
// YYDuckObj.h | |
// YYDuckObj | |
// | |
// Created by yauzz on 17/8/13. | |
// Copyright © 2017年 yauzz. All rights reserved. | |
// | |
#import <Foundation/Foundation.h> | |
@interface YYDuckObj : NSObject | |
@property (nonatomic, strong) NSMutableDictionary *propertys; | |
- (instancetype)initWithProtocol:(Protocol *)aProtocol; | |
@end |
This file contains 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
// | |
// YYDuckObj.m | |
// YYDuckObj | |
// | |
// Created by yauzz on 17/8/13. | |
// Copyright © 2017年 yauzz. All rights reserved. | |
// | |
#import "YYDuckObj.h" | |
#import <YYModel/YYClassInfo.h> | |
#import <objc/objc.h> | |
@interface YYDuckObj () | |
@property (nonatomic, copy) NSDictionary *propertyInfos; | |
@end | |
@implementation YYDuckObj | |
- (instancetype)initWithProtocol:(Protocol *)aProtocol | |
{ | |
self = [super init]; | |
if (self) { | |
unsigned int outCount; | |
NSMutableDictionary *dicts = [NSMutableDictionary dictionary]; | |
objc_property_t *pro = protocol_copyPropertyList(aProtocol, &outCount); | |
for (int i = 0; i < outCount; i++) { | |
YYClassPropertyInfo *info = [[YYClassPropertyInfo alloc] initWithProperty:pro[i]]; | |
[dicts setObject:info forKey:NSStringFromSelector(info.getter)]; | |
} | |
self.propertyInfos = dicts; | |
self.propertys = [NSMutableDictionary dictionary]; | |
} | |
return self; | |
} | |
+ (BOOL)resolveInstanceMethod:(SEL)sel | |
{ | |
return YES; | |
} | |
- (id)forwardingTargetForSelector:(SEL)aSelector | |
{ | |
return self; | |
} | |
- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector | |
{ | |
YYClassPropertyInfo *propertyInfo = [self.propertyInfos objectForKey:NSStringFromSelector(aSelector)]; | |
if (propertyInfo) { | |
if ([propertyInfo.typeEncoding isEqualToString:@"i"]) { | |
return [self methodSignatureForSelector:@selector(getMethodReturnInt32WithKey:)]; | |
} | |
} | |
return [super methodSignatureForSelector:aSelector]; | |
} | |
- (void)forwardInvocation:(NSInvocation *)anInvocation | |
{ | |
YYClassPropertyInfo *propertyInfo = [self.propertyInfos objectForKey:NSStringFromSelector(anInvocation.selector)]; | |
if (propertyInfo) { | |
if ([propertyInfo.typeEncoding isEqualToString:@"i"]) { | |
SEL originSel = anInvocation.selector; | |
anInvocation.selector = @selector(getMethodReturnInt32WithKey:); | |
[anInvocation setArgument:&originSel atIndex:2]; | |
} | |
[anInvocation invoke]; | |
} | |
} | |
- (id)getMethodReturnIDWithKey:(SEL)aSelector | |
{ | |
return @"hahahah"; | |
} | |
- (int)getMethodReturnInt32WithKey:(SEL)aSelector | |
{ | |
NSString *value = [self.propertys objectForKey:NSStringFromSelector(aSelector)]; | |
if (value) { | |
return value.intValue; | |
} else { | |
return 0; | |
} | |
} | |
@end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment