一:首先使用performSelector时要特别注意内存泄漏问题,下面代码演示:
创建一个控制器ZWWTestThreadViewController,从上个控制器push到该控制器,

ZWWLog的宏定义:

#ifdef DEBUG
#define ZWWLog(fmt, ...) NSLog((@"%s [Line %d] " fmt), __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__);
#else
#define ZWWLog(...)
#endif

ZWWTestThreadViewController.m输入代码:

- (void)viewDidLoad {[super viewDidLoad];ZWWLog(@"retainCount=%ld",CFGetRetainCount((__bridge CFTypeRef)self));//performSelector调用方法[self performSelector:@selector(testPerformSelectorFunc) withObject:self afterDelay:10.0];//直接调用方法
//    [self testPerformSelectorFunc];ZWWLog(@"retainCount=%ld",CFGetRetainCount((__bridge CFTypeRef)self));
}- (void)viewDidDisappear:(BOOL)animated{[super viewDidDisappear:animated];ZWWLog();
}//
- (void)testPerformSelectorFunc{ZWWLog();
}- (void)dealloc
{ZWWLog(@"对象被销毁");ZWWLog(@"retainCount=%ld",CFGetRetainCount((__bridge CFTypeRef)self));
}

情况1:当未达到10s就点击那navigationbar上的返回按钮退出此界面,打印结果:

结果:
1.执行performSelector后,self.retainCount是会增加的,先不管为什么是8,10(参考链接)
2.testPerformSelectorFunc在viewDidDisappear之后执行,也就是在页面返回disappear以后,dealloc方法并没有执行,控制器对象并没有真正销毁,造成了内存泄漏。而等达到10s时间的时候,虽然该控制器已经disappear了,但还会执行该页面的代码testPerformSelectorFunc方法,执行完这个方法,才执行了dealloc方法,对象才得到了释放,证明执行完performSelector方法后self.retainCount会对应减少

情况2:达到10s,再退出页面,打印结果:

结果:
1.执行viewDidDisappear之后就会执行dealloc,对象得到了真正释放。执行dealloc时reatainCount肯定为1,之前reatainCount是几不是特别重要(参考链接)

解决方法:
在界面或者控制器退出的时候取消那些还没有来得及执行的延时函数,代码很简单:

[NSObject cancelPreviousPerformRequestsWithTarget:self]

当然你也可以一个一个得这样用:

[NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(method1:) object:nil]

加上了这个以后,dealloc方法就会被调用,问题解决!

viewDidDisappear方法里面添加代码 [NSObject cancelPreviousPerformRequestsWithTarget:self];

- (void)viewDidDisappear:(BOOL)animated{[super viewDidDisappear:animated];ZWWLog();[NSObject cancelPreviousPerformRequestsWithTarget:self];
}

运行结果:

结论:可以看到即使没到10s退出该控制器,也会立即执行dealloc方法,对象销毁,而且testPerformSelectorFunc不会在viewDidDisappear之后再执行

二:下面我们再说下performSelector原理及用法

在上面viewDidLoad可以看到,我们调用方法(发送消息)时经常是直接调用方法,那和performSelector区别是什么?

- (void)viewDidLoad {[super viewDidLoad];ZWWLog(@"retainCount=%ld",CFGetRetainCount((__bridge CFTypeRef)self));//performSelector调用方法[self performSelector:@selector(testPerformSelectorFunc) withObject:self afterDelay:10.0];//直接调用方法
//    [self testPerformSelectorFunc];ZWWLog(@"retainCount=%ld",CFGetRetainCount((__bridge CFTypeRef)self));
}

1、performSelector是运行时系统负责去找方法的,在编译时候不做任何校验;如果直接调用编译时会自动校验。如果testPerformSelectorFunc方法不存在,那么直接调用 在编译时候就能够发现(借助Xcode提示方法全名就发现),但是使用performSelector的话一定是在运行时候才能发现(此时程序崩溃);Cocoa支持在运行时向某个类添加方法,即方法编译时不存在,但是运行时候存在,这时候必然需要使用performSelector去调用。所以有时候如果使用了performSelector,为了程序的健壮性,会使用检查方法- (BOOL)respondsToSelector:(SEL)aSelector;

2、直接调用方法时候,一定要在头文件中声明该方法的使用,也要将头文件import进来。而使用performSelector时候,可以不用import头文件包含方法的对象,直接用performSelector调用即可。

performSelector 注意问题及原理相关推荐

  1. performSelector的原理及应用场景分析

    文章目录 1.performSelector实现原理 2.performSelector触发时机 3.performSelector 与 dispatch_source_t(事件联结)的区别 4.注意 ...

  2. performSelector的原理以及用法

    一.performSelector调用和直接调用区别 下面两段代码都在主线程中运行,我们在看别人代码时会发现有时会直接调用,有时会利用performSelector调用,今天看到有人在问这个问题,我便 ...

  3. iOS performSelector的原理以及用法

    一.performSelector调用和直接调用区别 下面两段代码都在主线程中运行,我们在看别人代码时会发现有时会直接调用,有时会利用performSelector调用,今天看到有人在问这个问题,我便 ...

  4. iOS底层原理 - 常驻线程

    iOS底层原理 - 常驻线程 在 AFN 2.0 时代,会经常看到 AFN 创建一个常驻线程的方式: 0️⃣ AFN 2.0 时代的常驻线程 + (NSThread *)networkRequestT ...

  5. 趣谈iOS运行时的方法调用原理

    一个成熟的计算机语言必然有丰富的体系,复杂的容错机制,处理逻辑以及判断逻辑.但这些复杂的逻辑都是围绕一个主线丰富和展开的,所以在学习计算机语言的时候,先掌握核心,然后了解其原理,明白程序语言设计的实质 ...

  6. NSNotification消息通知实现源码(观察者模式原理)

    先简单介绍苹果封装的消息通知,再献上根据观察者模式原理实现的源码供参考. 消息通知 对于观察者模式,苹果封装了消息通知(NSNotification)和通知中心(NSNotificationCente ...

  7. IOS SEL (@selector) 原理及使用总结(一)

    SEL 类成员方法的指针 可以理解 @selector()就是取类方法的编号,他的行为基本可以等同C语言的中函数指针,只不过C语言中,可以把函数名直接赋给一个函数指针,而Object-C的类不能直接应 ...

  8. iOS底层原理探究-Runloop

    Runloop 1. 概述 一般来说,一个线程只能执行一个任务,执行完就会退出,如果我们需要一种机制,让线程能随时处理时间但并不退出,那么 RunLoop 就是这样的一个机制.Runloop是事件接收 ...

  9. React Native 从入门到原理

    React Native 是最近非常火的一个话题,介绍如何利用 React Native 进行开发的文章和书籍多如牛毛,但面向入门水平并介绍它工作原理的文章却寥寥无几. 本文分为两个部分:上半部分用通 ...

最新文章

  1. VC使用ActiveX控件常见问题
  2. java 人事_java版简易人事管理系统
  3. 如何在fluid中添加自定义控件
  4. leetcode刷题 60 61
  5. node 获取mysql数据类型,node连接mysql获取数据
  6. No module factory available for dependency type: CssDependency
  7. 一位准程序员对软件行业的8个问题
  8. EXCEL下载功能在XP系统中运行是好好的,到windows2003系统上,就报错
  9. [leetcode]1131. 绝对值表达式的最大值 ---曼哈顿距离,四角思维
  10. [转]用户空间和内核空间,进程上下文和中断上下文
  11. 天地伟业中间件服务器设置硬盘,如何设置服务器的镜像磁盘
  12. hdu 1247 Hat’s Words 字典树
  13. 读书笔记:程序员的工具箱之“代码片段”
  14. NPOI导出Excel2007-xlsx格式文件,用于web时需要注意的问题-XSSFWorkbook处理问题
  15. 如何走向真正的智能?
  16. 利用微信搜索抓取公众号文章
  17. unity blend 笔记
  18. Qt:解决跨线程调用socket/IO类,导致报错的问题(socket notifiers cannot be enabled from another thread)
  19. 分享一次联想笔记本的售后体验
  20. 华为荣耀9青春版系统像鸿蒙,荣耀9青春版参数配置

热门文章

  1. 试用Google工具条的网页翻译!
  2. R中的留一法交叉验证(带有示例)
  3. 怒肝 Java 学习路线一条龙!
  4. 开始学习es(饿死)
  5. 张宇1000题高等数学 第二章 数列极限
  6. 元件封装知识(转载)
  7. 《 硬件创业:从产品创意到成熟企业的成功路线图》——1.3 当今硬件企业类型...
  8. (转)通用权限管理设计 之 数据权限
  9. 服务器 在线系统安装,NF5280服务器操作系统安装说明.pdf
  10. 如何在一个html页面中引入另一个html页面