SEL類型
Objective-C在編譯的時候,會根據方法的名字(包括參數序列),生成一個用 來區分這個方法的唯一的一個ID,這個ID就是SEL類型的。我們需要注意的是,只要方法的名字(包括參數序列)相同,那麼它們的ID都是相同的。就是 說,不管是超類還是子類,不管是有沒有超類和子類的關系,只要名字相同那麼ID就是一樣的。
SEL方式
1.SEL 變量名 = @selector(方法名字);
2.SEL 變量名 = NSSelectorFromString(方法名字的字符串);
3.NSString *變量名 = NSStringFromSelector(SEL參數);
其中第1行是直接在程序裡面寫上方法的名字,
第2行是寫上方法名字的字符串,
第3行是通過SEL變量獲得方法的名字。
我們得到了SEL變量之後,可以通過下面的調用來給一個對象發送消息:
[對象 performSelector:SEL變量 withObject:參數1 withObject:參數2];
這樣的機制大大的增加了我們的程序的靈活性,我們可以通過給一個方法傳遞SEL參數,讓這個方法動態的執行某一個方法;我們也可以通過配置文件指定需要執行的方法,程序讀取配置文件之後把方法的字符串翻譯成為SEL變量然後給相應的對象發送這個消息。
從效率的角度上來說,執行的時候不是通過方法名字而是方法ID也就是一個整數來查找方法,由於整數的查找和匹配比字符串要快得多,所以這樣可以在某種程度上提高執行的效率。
這裡我講一下selector 多參數的問題
@interface NSObject (MoreSelctorParam)
-(id)performSelector:(SEL)aSelector withObjects:(NSArray*) objects;
@end
@implementation NSObject (MoreSelctorParam)
-(id)performSelector:(SEL)selector withObjects:(NSArray*) objects
{
NSMethodSignature *signature = [self methodSignatureForSelector:selector];//方法簽名
if (signature)//如果簽名成功
{
NSInvocation* invocation = [NSInvocation invocationWithMethodSignature:signature];//調用
[invocation setTarget:self];
[invocation setSelector:selector];//調用誰呢?selector啊!
for(int i = 0; i <[objects count]; i++)
{
id object = [objects objectAtIndex:i];
[invocation setArgument:&object atIndex: (i + 2)];//為什麼在2 因為 0 和1 被target 和selector占用了。。
}
[invocation retainArguments];//防止被釋放
[invocation invoke];//調用
//有返回值
if (signature.methodReturnLength)
{ www.2cto.com
id anObject;
[invocation getReturnValue:&anObject];
return anObject;
} else
{
return nil;
}
}
else//不成功
{
return nil;
}
}
@end
問題就出現了 不知道你們注意沒有?
-(void) printInt:(int)i String:(NSString *)s;
-(void) printInt:(NSInteger)i String:(NSString *)s;
-(void) printInt:(id)i String:(NSString *)s;
[obj performSelector:@selector(printInt:String:) withObjects:[NSArray arrayWithObjects:[[NSNumber alloc]initWithInt:5],@"this string", nil]];
前2個結果為 i-> 151608432,s->this string
後一個結果為 i-> 5,s->this string