首页 > 编程知识 正文

ios13(iOS performSelector的原理以及用法)

时间:2023-05-04 19:14:17 阅读:123558 作者:2506

一、performSelector调用和直接调用区别

以下两个代码都在主线程上执行。 查看别人的代码时,它可能直接调用,也可能使用performSelector调用。 我今天看到了问这个问题的人,所以总结一下。

[ delegateimagedownloader : selfdidfinishwithimage : image ]

[ delegateperformselector : @ selector (image downloader : didfinishwithimage : ) with object : selfwithobject 3360 imath

1、performSelector负责运行时系统查找方法,编译时不做任何检查; 直接调用编译时会自动验证。 如果image downloader:didfinishwithimage : image :不存在,则可以在编译时发现直接调用,但performSelector始终可以在运行时发现(此时程序可以在Cocoa支持在运行时将方法添加到类中。 也就是说,在编译方法时不存在,但在运行时存在。 在这种情况下,必须使用performSelector进行调用。 因此,使用performSelector时,为了程序健壮性,是一种检查方法(- (BOOL ) respondstoselector: ) sel ) aSelector;

2、直接调用方法时,必须在头文件中声明该方法的使用,头文件也必须导入。 此外,如果使用performSelector,则可以直接在performSelector中调用它,而无需在import头文件中使用包含方法的对象。二、常用的performSelector简单分析

1.

-id )性能选择器: (sel ) a选择器;

-id )性能选择器: (sel ) aselectorwithobject : (id ) object;

-(id ) performselector:(sel ) aselectorwithobject3360 ) id ) object1with object : (id ) object2;

这三种方法都是并发的,无论线程如何,都会在主线程和子线程上成功调用。 与直接调用方法相同。 在需要动态调用方法时使用。

示例(selfperformselector : @ selector (test2); [自我测试2 ]; 执行效果完全一样。

2.

-(void ) performselector:(sel ) aselectorwithobject : (id ) anargumentafterdelay : (ns time interval ) delayinmooin

-(void ) performselector:(sel ) aselectorwithobject : (id ) anargumentafterdelay : (ns time interval ) delay;

这两种方法都是异步执行,即使delay参数为0,也是异步执行。 只能在主线程上运行,而不在子线程上移动到aSelector方法。 当单击UI中的按钮时,将发生一个消耗系统性能的事件,并且按钮在事件运行时将保持突出显示时可用。 在这种情况下,可以通过调用此方法异步处理事件来避免上述问题。

如果方法未达到执行时间,则取消方法如下:

(void ) cancelpreviousperformrequestswithtarget : (id ) atargetselector 3360 (sel ) aselectorobject3360 ) id ) anArgument

(void ) cancelpreviousperformrequestswithtarget : (id ) aTarget;

注:为了避免内存泄漏,请在调用方法之前或方法所在的viewController生命周期结束时调用取消函数。

3.

-(void ) performselectoronmainthread : (sel ) aselectorwithobject:(id ) argwaituntildone3360(bool ) wait modes 3360

-(void ) performselectoronmainthread : (sel ) aselectorwithobject:(id ) argwaituntildone:(bool ) wait;

这两个方法都可以在主线程和子线程上执行,它们都调用主线程的aSelector方法。

如果wait设置为YES:则在当前线程执行完成之前,主线程不会执行aSelector方法。

如果设置为NO,则在主线程上执行aSelector方法,而不等待当前线程完成。

如果当前线程是主线程,则aSelector方法将立即执行。

注意: apple不允许程序员在主线程以外的线程上操作ui。 在这种情况下,必须调用performSelectorOnMainThread函数在主线程上完成ui更新。

r>
4.
- (void)performSelector:(SEL)aSelector onThread:(NSThread *)thr withObject:(id)arg waitUntilDone:(BOOL)wait modes:(NSArray *)array;
- (void)performSelector:(SEL)aSelector onThread:(NSThread *)thr withObject:(id)arg waitUntilDone:(BOOL)wait;
调用指定线程中的某个方法。分析效果同3。

5.
- (void)performSelectorInBackground:(SEL)aSelector withObject:(id)arg
开启子线程在后台运行

三、示例
首先建立一个简单的函数
- (void) fooNoInputs {
NSLog(@"Does nothing");
}
然后调用它[self performSelector:@selector(fooNoInputs)];

第二个试验看看如何在消息中传递参数
我们建立一个有input参数的函数
- (void) fooOneIput:(NSString*) first {
NSLog(@"Logs %@", first);
}
然后调用它[self performSelector:@selector(fooOneInput:) withObject:@"first"];

第三个试验更多的参数
- (void) fooFirstInput:(NSString*) first secondInput:(NSString*) second {
NSLog(@"Logs %@ then %@", first, second);
}
然后调用它
[self performSelector:@selector(fooFirstInput:secondInput:) withObject:@"first" withObject:@"second"];
第四个试验如何建立动态的函数,然后调用他们?我们需要建立一个selector
SEL myTestSelector = @selector(myTest:);
并且我们调用的函数在另外一个Class内
- (void)abcWithAAA: (NSNumber *)number {
int primaryKey = [number intValue];
NSLog("%i", primaryKey);
}
MethodForSelectors * mfs = [[MethodForSelectors alloc]init];
NSArray *Arrays = [NSArray arrayWithObjects:@"AAA", @"BBB", nil];
for ( NSString *array in Arrays ){
SEL customSelector = NSSelectorFromString([NSStringstringWithFormat:@"abcWith%@:", array]);
mfs = [[MethodForSelectors alloc] performSelector:customSelector withObject:0];
}
注意:updated at 20120606

1.如果使用了ARC会产生“performSelector may cause a leak because its selector is unknown”警告
2.这种方式当传入一个不符合约定的消息时会继续运行并不报错。例如应该传入2个参数,但只传入1个参数。或传入了3个参数,第三个参数不会被初始化。
还有一种调用其他Class Function的方法是,但是不能有参数,我们这里假设没有参数,那么就可以这样[mfs customSelector]; 

完整的代码:


@implementation ClassForSelectors
- (void) fooNoInputs {
NSLog(@"Does nothing");
}
- (void) fooOneIput:(NSString*) first {
NSLog(@"Logs %@", first);
}
- (void) fooFirstInput:(NSString*) first secondInput:(NSString*) second {
NSLog(@"Logs %@ then %@", first, second);
}
 
- (NSArray *)abcWithAAA: (NSNumber *)number {
int primaryKey = [number intValue];
NSLog("%i", primaryKey);
}
 
- (void) performMethodsViaSelectors {
[self performSelector:@selector(fooNoInputs)];
[self performSelector:@selector(fooOneInput:) withObject:@"first"];
[self performSelector:@selector(fooFirstInput:secondInput:) withObject:@"first" withObject:@"second"];
}
 
- (void) performDynamicMethodsViaSelectors {
MethodForSelectors * mfs = [MethodForSelectors alloc];
NSArray *Arrays = [NSArray arrayWithObjects:@"AAA", @"BBB", nil];
for ( NSString *array in Arrays ){
SEL customSelector = NSSelectorFromString([NSStringstringWithFormat:@"abcWith%@:", array]);
mfs = [[MethodForSelectors alloc] performSelector:customSelector withObject:0];
}
}
@end
 
@implementation MethodForSelectors
- (void)abcWithAAA: (NSNumber *)number {
NSLog("%i", number);
}
@end

-- NORMAL --

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。