performSelector 注意问题及原理

performSelector 注意问题及原理1 首先使用 performSelec 是要特别注意内存泄漏问题 下面代码演示 创建一个控制器 ZWWTestThrea 从上个控制器 push 到该控制器 ZWWLog 的宏定义 ifdefDEBUG defineZWWLog fmt NSLog s Line d fmt PRETTY FUNCTION

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)); }

[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]; } 

二:下面我们再说下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调用即可。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/233769.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号