zoukankan      html  css  js  c++  java
  • 几个常用的回调方法

    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];
    }
  • 相关阅读:
    月薪3万+的大数据人都在疯学Flink,为什么?
    Flink应用场景
    Flink生态与未来
    flink学习笔记-split & select(拆分流)
    .NET MVC5简介(四)Filter和AuthorizeAttribute权限验证
    .NET MVC5简介(三)Result
    .NET MVC5简介(二)
    VUE基础实用技巧
    .NET MVC5简介(一)
    WebApi简介
  • 原文地址:https://www.cnblogs.com/CoderWayne/p/3410711.html
Copyright © 2011-2022 走看看