话说今儿个,咱来聊聊 Objective-C 里的一个挺有意思的玩意儿——performSelector
。这东西,说白就是能让你在程序跑起来的时候,动态地去叫唤(调用)一个方法。听着有点玄乎?别急,咱慢慢捋。
我是为解决一个啥问题?就是想在主线程里头,搞点跟界面有关的活儿。你想,iOS 里头,跟界面打交道的事儿,基本都得在主线程里做,不然容易出岔子。可有时候,你又不想直接把代码写死,就想灵活点,这时候performSelector
就派上用场。
我先是查查这performSelector
到底是个网上一搜,好家伙,原来这东西的原理,就是运行时系统帮你去找方法。啥叫运行时?就是程序跑起来的时候呗。编译的时候,它可不管你,你爱写啥写只要格式对就行。但真跑起来,它就得去内存里头,找到你说的那个方法,然后执行它。
然后我就琢磨着,这玩意儿咋用?最简单的用法,就是[对象 performSelector:@selector(方法名)]
。比方说,我有个按钮,想在点击之后,过一会儿再执行一个叫doSomething
的方法,我就这么写:
[self performSelector:@selector(doSomething) withObject:nil afterDelay:2.0];
瞧见没,withObject:nil
就是说,这个方法不需要参数,afterDelay:2.0
就是说,等两秒再执行。还挺方便。
后来我又发现,这performSelector
还能传参数!不过它最多只能传俩参数。你要是想传更多参数,那就得想别的辙。传参数咋传?就用withObject:
。比方说,我要给doSomething
方法传个字符串,我就这么写:
[self performSelector:@selector(doSomething:) withObject:@"Hello, World!"];
看到,方法名后面多个冒号,表示这方法需要一个参数。然后在withObject:
后面,把你要传的参数写上就行。
再后来我又琢磨,这performSelector
能不能在子线程里用?一试,还真行!不过它默认是在当前线程执行的。也就是说,你在哪个线程里叫唤它,它就在哪个线程里干活。你要是想让它在主线程里干活,就得这么写:
[self performSelectorOnMainThread:@selector(doSomething) withObject:nil waitUntilDone:YES];

performSelectorOnMainThread
,顾名思义,就是在主线程上执行。waitUntilDone:YES
是说,等这个方法执行完,再继续往下走。你要是不想等,就写NO
。
不过用performSelector
的时候,也得留点神。因为它是在运行时才去找方法的,所以编译器不会帮你检查方法名写没写对。你要是写错,编译的时候不会报错,但跑起来就得崩溃。用的时候,一定得仔细点,别写错方法名。
还有就是,它最多支持两个参数,如果参数再多,就比较麻烦。虽然也有办法绕过去,但是不建议大家强行这么玩。
performSelector
这东西,还是挺有用的。它能让你的代码更灵活,更动态。但是,用的时候也得小心,别玩脱。今儿个就聊这么多,希望对大伙儿有所帮助!