Skip to content

Instantly share code, notes, and snippets.

@YauzZ
Created August 13, 2017 15:32
Show Gist options
  • Save YauzZ/d5a6bedeac6588454f5f57204416bd3a to your computer and use it in GitHub Desktop.
Save YauzZ/d5a6bedeac6588454f5f57204416bd3a to your computer and use it in GitHub Desktop.
鸭子对象例子
//
// 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
//
// 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