zoukankan      html  css  js  c++  java
  • iOS方法调用的几种方式

    iOS调用一个方法基本上有四种方式:1)直接对类调用类方法,对象调用对象方法。2)使用performSelector的方式调用。3)使用NSInvocation调用方法。4)使用runtime,ojbc_msgSend调用。

    1)直接调用

    [self getPropertyList];
    [self getIvarList];
    [self getInstanceMethodList];
    [self getClassMethodList];

    2)使用performSelector的方式调用,

    performSelector是运行时系统负责去找方法的,在编译时候不做任何校验;如果直接调用编译是会自动校验。如果imageDownloader:didFinishWithImage:image:不存在,那么直接调用在编译时候就能够发现(借助Xcode可以写完就发现),但是使用performSelector的话一定是在运行时候才能发现(此时程序崩溃);Cocoa支持在运行时向某个类添加方法,即方法编译时不存在,但是运行时候存在,这时候必然需要使用performSelector去调用。所以有时候如果使用了performSelector,为了程序的健壮性,会使用检查方法
    if ([obj.observer respondsToSelector:obj.selecotr]) {
                [obj.observer performSelector:obj.selecotr withObject:obj];
    }

    3)使用NSInvocation去调用方法

    //创建一个函数签名,这个签名可以是任意的,但需要注意,签名函数的参数数量要和调用的一 致。
    SEL myMethod =@selector(privateMethod);
    //通过签名初始化
    NSMethodSignature* sig = [NSNumber instanceMethodSignatureForSelector:@selector(init)];
    NSInvocation* invocatin = [NSInvocation invocationWithMethodSignature:sig];
    //设置target
    [invocatin setTarget:self];
    //设置selecteor
    [invocatin setSelector:myMethod];
    //消息调用
    [invocatin invoke];

    注意:1、这里设置参数的Index 需要从2开始,因为前两个被selector和target占用。下面这样写也没有任何问题:2、这里的传参方式必须是传递参数地址。

    4)objc_msgSend的写法要复杂一点,具体可以参看这篇文章,讲的很清楚

    http://www.jianshu.com/p/efeb33712445

    但是有个缺点是,需要指定好传递参数的类型,是不是可以直接都用id呢?

    经测试id可用

    // objc_msgSend
    SEL sel = NSSelectorFromString(@"printWithString:withNum:withArray:");
    ((void (*) (id, SEL, NSString *, NSNumber *, NSArray *)) objc_msgSend) (self, sel, str, num, arr);
  • 相关阅读:
    struct2 学习总结
    c++ 容器(list学习总结)
    java 网络编程(五)----TCP进阶篇上传文本文件
    java 网络编程(四)----UDP进阶篇聊天小程序
    java 网络编程(三)---TCP的基础级示例
    java 网络编程(二)----UDP基础级的示例
    java 网络编程(一)---基础知识和概念了解
    GitHub和git和repo的使用
    android studio不能预览
    关于android studio2.3和android studio3.0
  • 原文地址:https://www.cnblogs.com/sunyaxue/p/9741599.html
Copyright © 2011-2022 走看看