iOS实现调用动态方法名有返回值的方法

需求:

有10个类, 每个类里头都有n个方法(前提是方法名有规律可循,比如 setA0,setA1…)  如果挨个去init类, 然后挨个调用方法,这样你一天就不用干别的了

简单的解决方法可以参考这个: iPhone开发中,动态调用类和方法

虽然说performSelector有返回值,但是在ARC下会有警告,因为方法名是动态的,系统并不知道返回值是什么样的类型。解决方法可以见这篇文章: "performSelector may cause a leak because its selector is unknown"警告原因及其解决办法

全文转载过来:

问题描述

项目中使用到了从字符串创建选择器,编译时发现警告:"performSelector may cause a leak because its selector is unknown"(因为performSelector的选择器未知可能会引起泄漏),为什么在ARC模式下会出现这个警告?

经过搜索后,在Stackoverflow上发现了一个令人满意的答案。见http://stackoverflow.com/questions/7017281/performselector-may-cause-a-leak-because-its-selector-is-unknown

原因

在ARC模式下,运行时需要知道如何处理你正在调用的方法的返回值。这个返回值可以是任意值,如void,int,char,NSString,id等等。ARC通过头文件的函数定义来得到这些信息。所以平时我们用到的静态选择器就不会出现这个警告。因为在编译期间,这些信息都已经确定。

如:

...
[someController performSelector:@selector(someMethod)];
...
- (void)someMethod
{  //bla bla...}

而使用[someController performSelector: NSSelectorFromString(@"someMethod")];时ARC并不知道该方法的返回值是什么,以及该如何处理?该忽略?还是标记为ns_returns_retained还是ns_returns_autoreleased?

解决办法

1.使用函数指针方式

SEL selector = NSSelectorFromString(@"someMethod");IMP imp = [_controller methodForSelector:selector];void (*func)(id, SEL) = (void *)imp;func(_controller, selector);

当有额外参数时,如

SEL selector = NSSelectorFromString(@"processRegion:ofView:");IMP imp = [_controller methodForSelector:selector];CGRect (*func)(id, SEL, CGRect, UIView *) = (void *)imp;CGRect result = func(_controller, selector, someRect, someView);

2.使用宏忽略警告

#pragma clang diagnostic push 
#pragma clang diagnostic ignored "-Warc-performSelector-leaks" 
   [someController performSelector: NSSelectorFromString(@"someMethod")]
#pragma clang diagnostic pop

通过使用#pragma clang diagnostic push/pop,你可以告诉Clang编译器仅仅为某一特定部分的代码来忽视特定警告。

如果需要忽视的警告有多处,可以定义一个宏

#define SuppressPerformSelectorLeakWarning(Stuff) \    do { \        _Pragma("clang diagnostic push") \        _Pragma("clang diagnostic ignored \"-Warc-performSelector-leaks\"")         Stuff; \        _Pragma("clang diagnostic pop")     } while (0)

在产生警告也就是performSelector的地方用使用该宏,如

SuppressPerformSelectorLeakWarning(
    [_target performSelector:_action withObject:self]
);

如果需要performSelector返回值的话,

id result;SuppressPerformSelectorLeakWarning(
    result = [_target performSelector:_action withObject:self]
);

3.使用afterDelay

[self performSelector:aSelector withObject:nil afterDelay:0.0];

如果在接受范围内,允许在下一个runloop执行,可以这么做。xCode5没问题,但据反映,xCode6的话这个不能消除警告。

时间: 2024-10-07 22:27:24

iOS实现调用动态方法名有返回值的方法的相关文章

13 继续C#中的方法,带返回值的方法介绍

在这一个练习中,我们要使用带返回值的方法.如果一个方法带返回值,那么它的形式是这样的. 定义一个带返回值的C#方法 static 返回类型 方法名字 (参数类型 参数1的名字,参数类型 参数2的名字) { 你的代码 return 返回值 } static: 先不用管是什么意思.在没有讲它的含义之前,在你写的每个方法中都要加上它. 返回类型:就是我们前面讲过的数据类型,int,string等等.通常一个方法调用后要给调用这个方法的地方返回一个值. 方法名字:你可以给方法起一个你想要的名字.不能瞎起

JSF页面中使用js函数回调后台bean方法并获取返回值的方法

由于primefaces在国内使用的并不是太多,因此,国内对jsf做系统.详细的介绍的资料很少,即使有一些资料,也仅仅是对国外资料的简单翻译或者是仅仅讲表面现象(皮毛而已),它们的语句甚至还是错误的,很可能会误导使用者. 相对来说,看国内的那些仅仅是翻译过来的文章或书籍不如直接看国外的官方文档或资料来的实在,在我讲述jsf页面中如何使用js调用后台bean方法之前,先给大家说几个国外的资料.在primefaces官方网站上,你可以搜索到几乎所有你需要的东西,primefaces官网为:http:

第三次博客作业package com.fry; //导入java.util.Arrays; import java.util.Arrays; public class Demo1 { public static void main(String[]args){ //创建对象,对象名为hello Demo1 hello =new Demo1(); //调用方法并将返回值保存在变量中

1.  某网站管理系统,用户注册时,电话号码为可选输入项,输入格式为:区号-电话号码—分机号,中间用“-”隔开.以下为jsp页面上的设计,且并未对输入做任何控制. 假设系统现在需要取出中间的电话号码部分,代码如下: /** * * 该方法根据用户输入取出中间的电话号码部分 * @param strPhoneNum 电话号码,如:“0591-83279988—002” * @return 返回号码部分,如:“83279988” */ public String getPhoneNumber(Str

基础才是重中之重~Emit动态构建方法(参数和返回值)

回到目录 对于Emit我们知道它的可以动态构建程序集,类型,方法,属性等,或者说只要手动使用C#创建的东西使用Emit也都可以动态创建它们,Emit由于它的特别之处,所以在很多领域得到了广泛的应用,像最近比较火的AOP技术,它最核心的功能就是方法拦截了,我们使用Emit也是可以实现方法拦截功能的,详细可以看大叔这篇文章<Lind.DDD.Aspects通过Plugins实现方法的动态拦截~Lind里的AOP>. 有参数,没有返回值的方法构建与调用 [TestMethod] public voi

Java加载jar文件并调用jar文件当中有参数和返回值的方法

在工作当中经常遇到反编译后的jar文件,并要传入参数了解其中的某些方法的输出,想到Java里面的反射可以实现加载jar文件并调用其中的方法来达到自己的目的.就写了个Demo代码. 以下的类可以编译生成hello.jar文件. 1 package org.lele.fatpanda; 2 3 public class Util 4 { 5 public static String myName; 6 /* 7 * 无参数,无返回值的方法. 8 */ 9 public static void get

atitit.架构设计---方法调用结果使用异常还是返回值

atitit.架构设计---方法调用结果使用异常还是返回值 1. 应该返回BOOL类型还是异常 1 2. 最终会有四种状况,抛出异常.返回特殊值.阻塞.超时 1 3. 异常的优缺点点 1 4. java BlockingQueue的提示 2 5. 方案::两个都使用,一个api返回bool,一个throw 异常... 2 1. 应该返回BOOL类型还是异常 现在我遇到一个问题,我有一个函数,它要实现的功能是启动一个线程,然后让此线程监视一个事件. 但我应该返回BOOL类型还是异常哪? 作者:: 

定义一个带参带返回值的方法,实现输出随机数数组

public class mains { public static void main(String[] args) { // 创建对象,对象名为hello mains hello = new mains(); // 调用方法并将返回值保存在变量中 int[] nums = hello.getArray(8); // 将数组转换为字符串并输出 System.out.println(Arrays.toString(nums)); } /* * 功能:创建指定长度的int型数组,并生成100以内随

javascript学习笔记(二):定义函数、调用函数、参数、返回值、局部和全局变量

定义函数.调用函数.参数.返回值 关键字function定义函数,格式如下: function 函数名(){ 函数体 } 调用函数.参数.返回值的规则和c语言规则类似. 1 <!DOCTYPE html> 2 <html> 3 <head lang="en"> 4 <meta chaset="UTF-8"> 5 <title></title> 6 </head> 7 <body

JAVA 类中方法参数与返回值

无参无返回值的方法,用public void 方法名,来声明: 有参无返回值的方法,用public void 方法名,来声明: 有参有返回值的方法,用public int 方法名(int i,int n),来声明(int 是参数的数据类型指定,也可以是其它数据类型,例如:String.char.double.int). 实例: //定义类 public class Test{ //无参无返回值的方法 public void eat(){ System.out.println("我在吃饭.&quo