performselector,performselector 返回值 内存泄露

http://www.itjxue.com  2023-01-09 01:17  来源:未知  点击次数: 

ios performselector怎么传多个参数

在NSObject.h可以看到

- (id)performSelector:(SEL)aSelector;

- (id)performSelector:(SEL)aSelector withObject:(id)object;

- (id)performSelector:(SEL)aSelector withObject:(id)object1 withObject:(id)object2;

这个方法最多传递两个id类型的参数。题主你可以换个思路,将参数包装成一个模型,这样一个模型就可以囊括所有的参数.

关于performSelector,怎么带参数

方法如下:

-(void)singleTap{

NSLog(@"Tap 1 time");

}

-(void)doubleTap{

NSLog(@"Tap 2 time");

}

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {

UITouch *touch = [touches anyObject];

NSTimeInterval delaytime = 0.4;//自己根据需要调整

switch (touch.tapCount) {

case 1:

[self performSelector:@selector(singleTap) withObject:nil afterDelay:delaytime];

break;

case 2:{

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

[self performSelector:@selector(doubleTap) withObject:nil afterDelay:delaytime];

}

break;

default:

break;

}

}

ios performselector 和 respondstoselector的区别

respondsToSelector是实例方法也是类方法,用于判断某个类/实例是否能处理某个方法(包括基类方法)。conformsToProtocol:@protocol()是用来检查对象是否实现了指定协议类的方法.respondsToSelector相关的方法:-(BOOL) isKindOfClass: classObj 用来判断是否是某个类或其子类的实例-(BOOL) isMemberOfClass: classObj 用来判断是否是某个类的实例-(BOOL) respondsToSelector: selector 用来判断是否有以某个名字命名的方法(被封装在一个selector的对象里传递)+(BOOL) instancesRespondToSelector: selector 用来判断实例是否有以某个名字命名的方法. 和上面一个不同之处在于, 前面这个方法可以用在实例和类上,而此方法只能用在类上.-(id) performSelector: selectorSEL sel = @selector (start:) ; // 指定action if ([obj respondsToSelector:sel]) { //判断该对象是否有相应的方法 [obj performSelector:sel withObject:self]; //调用选择器方法 } 使用[[UIApplication sharedApplication] keyWindow]查找应用程序的主窗口对象respondsToSelector判断是否实现了某方法#import Foundation/Foundation.h@interface Tester : NSObject {}-(void) test:(NSString*) msg;-(void) notImp;@endTester.m#import "Tester.h"@implementation Tester-(void) test:(NSString*) msg{NSLog(@"%@", msg);}@end注意:没有实现notImp方法main.m#import Foundation/Foundation.h#import "Tester.h"int main (int argc, const char * argv[]){NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];id tester = [[Tester alloc] init];//注意,这里使用idSEL testSelector = @selector(test:);SEL notImpSelector = @selector(notImp:);if([tester respondsToSelector:testSelector]){//tester.m中实现了test方法[tester test:@"invoke test method"];}if([tester respondsToSelector:notImpSelector]){//test.m中没有实现此主就去[tester notImp];}[pool drain];return 0;}conformsToProtocol:@protocol()是用来检查对象是否实现了指定协议类的方法//例子如下,在例子当中会有适当的注释,以助理解这个方法: @protocol MyProtocol - (void) doSomething; @end @interface MyClass : NSObjectMyProtocol//直接符合协议的类 { } @end @implementation MyClass - (void) doSomething { } @end @interface MyOtherClass : MyClass//继承了符合协议的类,即其父类符合协议。 { } @end @implementation MyOtherClass - (void) doSomething { } @end int main (int argc, const char * argv[]) { NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; MyClass *obj_one = [MyClass new]; BOOL one_conforms = [obj_one conformsToProtocol:@protocol(MyProtocol)]; MyOtherClass *obj_two = [MyOtherClass new]; //obj_two是类的实例对象,和父类相关,其父类符合协议,则其亦符合。 BOOL two_conforms = [obj_two conformsToProtocol:@protocol(MyProtocol)]; NSLog(@"obj_one conformsToProtocol: %d", one_conforms);//output:YES NSLog(@"obj_two conformsToProtocol: %d", two_conforms);//output:YES [pool drain]; return 0; } //Output: obj_one conformsToProtocol: 1 obj_two conformsToProtocol: 1 //Whereas: MyOtherClass *obj_two = [MyOtherClass new]; //class_conformsToProtocol是只检查当前类符不符合协议,和其父类无关。 BOOL conforms_two = class_conformsToProtocol([obj_two class], @protocol(MyProtocol)); NSLog(@"obj_two conformsToProtocol: %d", conforms_two);//output:NO //Output: obj_two conformsToProtocol: 0在代理调用是,检查其代理是否符合协议,或者使用 respondsToSelector 检查对象能否响应指定的消息,是避免代理在回调时因为没有实现代理函数而程序崩溃的一个有效的方式

swift里面没有performSelector,有替代的函数吗

Swift由于并非基于消息机制,所以本身没有selector这个十分灵活的机制,但是可以使用Cocoa Framework中所留下的一些selector,比如:

pre class="brush:objc; toolbar: true; auto-links: false;"

import UIKit

class MyViewController: UIViewController {

let myButton = UIButton(frame: CGRect(x: 0, y: 0, width: 100, height: 50))

init(nibName nibNameOrNil: String!, bundle nibBundleOrNil: NSBundle!) {

super.init(nibName: nibName, bundle: nibBundle) myButton.targetForAction("tappedButton:", withSender: self)

}

func tappedButton(sender: UIButton!) { println("tapped button")

} }

/pre

上述代码,"tappedButton:"就是一个selector,呵呵。

关于performSelector调用和直接调用有什么不同

1. 有一点是肯定的, performSelector是运行时系统负责去找函数/方法的,在编译时候不做任何校验;但是直接调用肯定在编译是会校验。如果test2不存在,那么直接调用 在编译时候就能够发现(借助Xcode可以写完就发现),但是使用performSelector的话一定是在运行时候才能发现(此时程序崩溃)

Cocoa支持在运行时 向某个类添加方法(应该极少人用到, 即方法编译时不存在,但是运行时候存在,这时候必然需要使用performSelector去调用)

大概这也是为什么写delegate的时候,为保证程序健壮性,会使用如下函数检验

- (BOOL)respondsToSelector:(SEL)aSelector;

iOS performSelector(参考)

在项目中,常常用到performSelector之类的方法,而且有很多类似方法;今天就来召集一下!

第一点 performSelector的使用

这里需要补充的知识: 关于performSelector调用和直接调用方法的区别

1、performSelector是运行时系统负责去找方法的,在编译时候不做任何校验;如果直接调用编译是会自动校验。

如果methodNoParam、methodWithOneParam:、methodWithParams: andParamSecond:不存在

那么直接调用:在编译时候就能够发现(借助Xcode可以写完就发现),但是使用performSelector的话一定是在运行时候才能发现(此时程序崩溃);

Cocoa支持在运行时向某个类添加方法,即方法编译时不存在,但是运行时候存在,这时候必然需要使用performSelector去调用。

所以有时候如果使用了performSelector,为了程序的健壮性,会使用检查方法respondsToSelector。

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

3、performSelector是在iOS中的一种方法调用方式。他可以向一个对象传递任何消息,而不需要在编译的时候声明这些方法。所以这也是runtime的一种应用方式。

所以performSelector和直接调用方法的区别就在与runtime。直接调用编译是会自动校验。如果方法不存在,那么直接调用 在编译时候就能够发现,编译器会直接报错。

但是使用performSelector的话一定是在运行时候才能发现,如果此方法不存在就会崩溃。所以如果使用performSelector的话他就会有个最佳伴侣respondsToSelector:;来在运行时判断对象是否响应此方法。

备注:runtime???

在这小作总结:OC是运行时语言,只有在程序运行时,才会去确定对象的类型,并调用类与对象相应的方法。利用runtime机制让我们可以在程序运行时动态修改类、对象中的所有属性、方法,就算是私有方法以及私有属性都是可以动态修改的。

// 动态添加方法

// 开发场景:如果一个类方法非常多,加载了到内存的时候也比较耗费资源,需给每个方法生成映射表,可以使用动态给某个类,添加方法解决.

// 经典面试题:有没有使用preformSelector,其实主要想问有没有添加过方法;

performSelector相关的应用:传递三个及以上的参数

第一种:NSInvocation

第二种:把多个参数封装成一个参数

在这里不做描述:详情参考

第三种:objc_msgSend

第二点

这里需要补充的知识:

Runloop 相当于 win32 里面的消息循环机制,它可以让你根据事件/消息(鼠标消息,键盘消息,触摸事件,计时器消息等)来调度线程。

比如:在触摸 UIView 时之所以能够激发 touchesBegan/touchesMoved 等等函数被调用。系统会自动为应用程序的主线程生成一个与之对应的 run loop 来处理其消息循环。让调用更加简单。也避免了繁琐,复杂的操作。

一句话:Runloop是一种消息处理机制!

参考链接:

(责任编辑:IT教学网)

更多

推荐SQL Server文章