您的位置:首页 > 其它

几个常用的回调方法

2013-11-06 15:45 148 查看
respondsToSelector与performSelector

这两个方法的优点是:
1. 与obj-c代码兼容性好。
2. 具有延迟执行特性。
3. 轻量级的回调机制。
缺点:
1. 回调产生的返回值只能为id类型,int等类型会产生错误。
2. 参数最多只能传入两个,但可以通过建立包含多个参数的类进行回避。同时返回值限制也可通过此方式解决,即建立一个输入类和一个输出类。
3. 即使在头文件里未声明该方法,也可以被调用到。

【示例1】利用respondsToSelector判断类是否实现了某方法:

Balloon.m

#import "Balloon.h"

@implementation Balloon

-(void) changeColor:(NSString *)color
{
NSLog(@"My favorite color is %@",color);
}

@end


ViewController.m

- (void)viewDidLoad
{
Balloon *balloon = [[Balloon alloc] init];

SEL changeColorFun = @selector(changeColor:);

if([balloon respondsToSelector:changeColorFun])
{
#pragma clang diagnostic pushs
#pragma clang diagnostic ignored "-Warc-performSelector-leaks"
[balloon performSelector:changeColorFun withObject:@"blue"];
#pragma clang diagnostic pop
}

[super viewDidLoad];
}


respondsToSelector还有一个类似的方法instancesRespondToSelector,它用来判断类是否包含某方法或属性,可以用该方法判断iOS系统的版本是否支持某个方法或者属性。上面的判断语句也可以改成:

if([Balloon instancesRespondToSelector:changeColorFun])


【示例2】通过performSelector延迟数秒后执行某一方法:

Balloon.m

#import "Balloon.h"

@implementation Balloon

-(void) changeColor:(NSString *)color
{
NSLog(@"My favorite color is %@",color);
}

@end


ViewController.m

- (void)viewDidLoad
{
SEL myFun = NSSelectorFromString(@"changeColor:");

Balloon *balloon = [[Balloon alloc] init];

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Warc-performSelector-leaks"
[balloon performSelector:myFun withObject:@"green" afterDelay:5];
#pragma clang diagnostic pop

[super viewDidLoad];
}


objc_msgSend

在Objective-C中,消息是直到运行的时候才和方法实现绑定的。编译器会把一个消息表达式转换成一个对消息函数objc_msgSend的调用。该函数有两个主要参数:消息接收者和消息对应的方法名字。

objc_msgSend(receiver, selector)


同时接收消息中的任意数目的参数:

objc_msgSend(receiver, selector, arg1, arg2, …)


通过导入#import <objc/message.h>获得运行时的消息调用。其定义为:

id objc_msgSend(id theReceiver, SEL theSelector, …)


优点:
1. 轻量级的回调机制。
2. 无传入参数限制。
3. 相比performSelector,使用自动引数特征时,不产生警告。
4. 同系列的方法支持double、struct等类型的返回值,但仍然不支持int类型返回值(可使用NSNumber包装以回避)。

缺点:
1. 传入不符合约定的消息时,产生副作用继续运行,而非报错。

【示例3】

User.m

#import "User.h"

@implementation User

-(NSString *) baseInfo:(NSString *)name from:(NSString *)city
{
return [NSString stringWithFormat:@"My name is %@,I come from %@",name,city];
}

@end


ViewController.m

#import "ViewController.h"
#import <objc/message.h>
#import "User.h"

@implementation ViewController

- (void)viewDidLoad
{
User *user = [[User alloc] init];
SEL myFun = NSSelectorFromString(@"baseInfo:from:");
NSString *strReturn = objc_msgSend(user, myFun,@"tom",@"beijing");
NSLog(@"return value is :%@",strReturn);

[super viewDidLoad];
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: