多用GCD 少用 performSelector 系列方法
OC 本质上是一门非常动态的语言, NSObject 定义了几个方法,令开发者可以调用任何方法, 这几个方法可以推迟执行方法调用, 也可以指定运行方法所用的线程,
这其中最简单的是 'performSelector' 该方法的签名如下, 它接受一个参数,就是要执行的那个选择子. - (id)performSelector:(SEL)selector
该方法与直接调用选择器等效,所以下面两行代码的执行效果相同
[object performSelector:@selector(selectorName)];
[object selectorName];
这种方式看上去多余, 但是如果选择子是在运行期决定的,那么就体现出此方式的强大之处, 这就等于在动态绑定之上再次使用动态绑定.
SEL selector;
if(xxx){
selector = @selector(foo);
}else{
selector = @selector(bar);
}
[object performSelector:selector];
这种编程方式极为灵活, 经常可以用来简化复杂的代码, 然而,使用次特性的代价是, 如果在 ARC 自爱编译代码, 那么编译器会发出如下警告信息.
warning: perfornSelector may cause a leak because its selector is unkonw
为什么警告会提到内存泄漏问题呢, 原因在于: 编译器并不知道将要调用的选择子是什么, 因此也不了解其方法签名及返回值, 甚至连是否有返回值都不清楚, 由于编译器不知道其方法名, 所以就没办法运用 ARC 的内存管理规则来判定返回值是不是应该释放, 鉴于此, ARC 采用了比较谨慎的做法,就是不添加释放操作, 然而这么做可能导致内存泄漏, 因为方法在返回对象时可能已经将其保留了.
使用 GCD 延后执行 或者 回到主线程执行
dispatch_time_t time = dispatch_time(DISPATCH_TIME_NOW,(int64_t)(5.0 * NSEC_PER_SEC));
dispatch_after(time,dispatch_get_main_queue(),^(void){
[self doSomething];
});
想把任务放在主线程上执行
dispatch_async(dispatch_get_main_queue(),^(void){
[self doSomething];
});
网友评论