Skip to content

replacement for -[NSObject performSelector:object:object:] using runtime

License

Notifications You must be signed in to change notification settings

michaelxiaonull/MXRuntimeUtils

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

23 Commits
 
 
 
 
 
 
 
 

Repository files navigation

MXRuntimeUtils is a replacement for -[NSObject performSelector:object:object:] and it's easy to use !

What's wrong with -[NSObject performSelector:object:object:]?

if you implementation a method just like codes below

- (id)testMethodWithIntValue:(int)aIntValue floatValue:(float)aFloatValue charValue:(char)aCharValue sizeValue:(CGSize)aCGSizeValue pointValue:(CGPoint)aCGPointValue edgeInsetsValue:(UIEdgeInsets)anUIEdgeInsetsValue stringValue:(NSString *)aStringValue idValue:(id)anIdValue {
    
    return @[@(aIntValue), @(aFloatValue), @(aCharValue), [NSValue valueWithCGSize:aCGSizeValue], [NSValue valueWithCGPoint:aCGPointValue], [NSValue valueWithUIEdgeInsets:anUIEdgeInsetsValue], aStringValue, anIdValue];
}

and you want to call -[self testMethodWithIntValue:floatValue:charValue:sizeValue:pointValue: edgeInsetsValue: stringValue:idValue:]using -[self performSelector:object:object:] , opps, you may get confused, because -[NSObject performSelector:withObject:withObject:]] only allow passing two parameters, and they are all declared id type, how can you pass basic data type just like BOOL, char, int, float and pass more than two parameters.

//[self performSelector:@selector(testMethodWithIntValue:floatValue:charValue:sizeValue:pointValue:edgeInsetsValue:stringValue:idValue:) withObject:one withObject:two ....];

How To Use

just one simple line code

[MXRuntimeUtils callMethodWithTarget:self selector:@selector(testMethodWithIntValue:floatValue:charValue:
sizeValue:pointValue:edgeInsetsValue:stringValue:idValue:) argumemts:@[@1, @2.0f, [NSNumber numberWithChar:'3'], [NSValue valueWithCGSize:CGSizeMake(4, 4)], 
[NSValue valueWithCGPoint:CGPointMake(5, 5)], [NSValue valueWithUIEdgeInsets:UIEdgeInsetsMake(6, 6, 6, 6)], @"7", @"8"] returnValue:&returnValue];

if your original method has a return value, please pass the pointer of your declared variable like this, *if you return type is OC object, note that you need declare an __autoreleasing variable like this __autoreleasing NSString stringReturnValue, __autoreleasing id idReturnValue, instead of strong OC object, the reason you can see in  memory management

//int returnValue 
int sumReturnValue = 0;
[MXRuntimeUtils callMethodWithTarget:self selector:@selector(sumWithAnIntValue:anotherIntValue) argumemts:@[@1, @2] returnValue:&returnValue];
//sumReturnValue = 3;

//id returnValue 
__autoreleasing id idReturnValue = nil;//avoid idReturnValue is dealloc after method invoking
[MXRuntimeUtils callMethodWithTarget:self selector:@selector(ConvertIntValueToIdType:) argumemts:@[@1] returnValue:&idReturnValue];
//idReturnValue = @1;

and you'll get number 3 from sumReturnValue, NSNumber 1 fromidReturnValue;

Sceeenshots

demo screenshot like this, but you may think a while, why I pass char value '3', converted to number is 51, actually char value '3' in ASCII is 51, just like 'A' is 65, 'a' is 97 and so on

Feature

  • Auto type checking

    if you pass an CGPoint type value to a method paramater which is declared int type, assertion is invoked, you'll see exception logs in your Xcode console something like this.

  • More than two parameters can be allowed

  • Any returnValue

 


中文介绍

MXRuntimeUtils 是用于替换 -[NSObject performSelector:object:object:]的工具,非常容易使用!

-[NSObject performSelector:object:object:] 出现哪些问题?

如果你想使用以下方法

- (id)testMethodWithIntValue:(int)aIntValue floatValue:(float)aFloatValue charValue:(char)aCharValue sizeValue:(CGSize)aCGSizeValue pointValue:(CGPoint)aCGPointValue edgeInsetsValue:(UIEdgeInsets)anUIEdgeInsetsValue stringValue:(NSString *)aStringValue idValue:(id)anIdValue {
    
    return @[@(aIntValue), @(aFloatValue), @(aCharValue), [NSValue valueWithCGSize:aCGSizeValue], [NSValue valueWithCGPoint:aCGPointValue], [NSValue valueWithUIEdgeInsets:anUIEdgeInsetsValue], aStringValue, anIdValue];
}

而且你想调用 -[self testMethodWithIntValue:floatValue:charValue:sizeValue:pointValue: edgeInsetsValue: stringValue:idValue:]但是用另一种方式来表达 -[self performSelector:object:object:] , 你可能感到懵逼, 因为 -[NSObject performSelector:withObject:withObject:]] 最高仅仅允许传两个值,而且还只能是id类型,那么,你怎么传基本数据类型,比如像 BOOL, char, int, float ,甚至超过两个参数的上限呢!

//[self performSelector:@selector(testMethodWithIntValue:floatValue:charValue:sizeValue:pointValue:edgeInsetsValue:stringValue:idValue:) withObject:one withObject:two ....];

如何使用

仅仅一行代码

[MXRuntimeUtils callMethodWithTarget:self selector:@selector(testMethodWithIntValue:floatValue:charValue:
sizeValue:pointValue:edgeInsetsValue:stringValue:idValue:) argumemts:@[@1, @2.0f, [NSNumber numberWithChar:'3'], [NSValue valueWithCGSize:CGSizeMake(4, 4)], 
[NSValue valueWithCGPoint:CGPointMake(5, 5)], [NSValue valueWithUIEdgeInsets:UIEdgeInsetsMake(6, 6, 6, 6)], @"7", @"8"] returnValue:&returnValue];

如果你的原始方法有一个返回值,那么就传一个返回值类型的指针,就像这样,如果你的返回值是一个OC对象, 注意要传一个 __autoreleasing 变量就像 这样 __autoreleasing NSString stringReturnValue, __autoreleasing id idReturnValue 而不是NSString stringReturnValue, id idReturnValue, 理由你可以看看这篇文章 memory management

//int returnValue 
int sumReturnValue = 0;
[MXRuntimeUtils callMethodWithTarget:self selector:@selector(sumWithAnIntValue:anotherIntValue) argumemts:@[@1, @2] returnValue:&returnValue];
//sumReturnValue = 3;

//id returnValue 
__autoreleasing id idReturnValue = nil;//avoid idReturnValue is dealloc after method invoking
[MXRuntimeUtils callMethodWithTarget:self selector:@selector(ConvertIntValueToIdType:) argumemts:@[@1] returnValue:&idReturnValue];
//idReturnValue = @1;

之后你就可以从sumReturnValue中得到数字3, idReturnValue中得到1

屏幕截图

示例代码中的demo 截图就像这样, 但是你会有点疑惑,为什么我传的值是字符类型char 3,转换成数字类型咋变成了51了,事实上, 在 ASCIIchar value '3' 就是 数字 51, 就像 'A'65, 'a' 是 97 一样 运行结果

特性

  • 自动类型检查

如果你传一个 CGPoint类型的值给一个 声明为int类型的方法参数,断言会触发,你会在Xcode控制台中得到以下截图信息

  • 允许传两个以上的参数

  • 得到任何类型的返回值 自动类型检查

About

replacement for -[NSObject performSelector:object:object:] using runtime

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published