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];
    }
  • 相关阅读:
    LeetCode "Median of Two Sorted Arrays"
    LeetCode "Distinct Subsequences"
    LeetCode "Permutation Sequence"

    LeetCode "Linked List Cycle II"
    LeetCode "Best Time to Buy and Sell Stock III"
    LeetCode "4Sum"
    LeetCode "3Sum closest"
    LeetCode "3Sum"
    LeetCode "Container With Most Water"
  • 原文地址:https://www.cnblogs.com/CoderWayne/p/3410711.html
Copyright © 2011-2022 走看看