(2018年3月22号重编)kkbox-ios-dev笔记(一) - Selector

2018年3月22号重编,复习,补充,完善。
2017年5月31号重编,简写。

Selector

  • Selector就是用字符串表示某个对象的某个方法

Objective-C Class/Object到底是什么?

  • Objective-C程序在编译运行时,会编译成 C语言。
  • Objective-C类会编译成 C的结构体,方法和block会被编译成 C 方法,
  • 在执行的时候,运行时会创建与C结构体和C方法的关联。

对类加入方法

  • 在执行的时候,Runtime会为每个类准备好一张表格,表格里面会以一个字符串key(又称:selector)对应到 C 方法的指定位置。把实现的 C 方法定义成IMP这个类型(又称:SEL,SEL就是C字串)。
  • 对一个对象调用某个方法,Runtime就把方法的名称当作字符串,寻找与字符串合适的 C 方法的实现,然后执行。
// 1: 这三种调用是一样的
[myObject doSomthing];

//2
[myObject performSelector:@selector(doSomething)];

//3
 objc_msgSend(myObject, @selector(doSomething), NULL);
  • 要求某个对象执行某个方法 = 要求某个对象执行某个 selector
  • 一个类有哪些方法,是在Runtime一个一个加入的,所以就有机会在程序正在执行时,继续对某个类操作。
  • OC中,一个类会有哪些方法,并不是固定的。
  • 如果不想用分类,而想要手动将某个方法加入到某个类,至少有两个参数,一个是执行的对象,一个是selector
// 目前不适应,仅供参考
//1 定义 C 方法
void myMethodIMP(id self, SEL _cmd) {
     doSomething();
}

//2 加入 selector 与对象的关系
class_addMethod([MyClass class], @selector(myMethod), (IMP)myMethodIMP, "v@:");

// 3. 调用
MyClass *myObject = [[MyClass alloc] init];
[myObject myMethod];

Selector用途

  • Selector主要用途就是实现target(谁调用?)/action(执行什么方法)
// 1. 定义
@interface MyButton : NSView
{
id target;
SEL action; }
@property (assign) IBOutlet id target;
@property (assign) SEL action;
@end
@implementation MyButton
- (void)mouseDown:(NSEvent *)e
{
   [super mouseDown:e];
   [target performSelector:action withObject:self];
}
@synthesize target, action;
@end
// 2.使用
[(MyButton *)button setTarget:self];
[(MyButton *)button setAction:@selector(clickAction:)];

检查方法是否存在

  • respondsToSelector:
BOOL scale = 1.0;
if ([[UIScreen mainScreen] >respondsToSelector:@selector(scale)])
{
   scale = [UIScreen mainScreen].scale;
}

Timer

// 1. 多久后执行
[self performSelector:@selector(doSomething) withObject:nil afte
rDelay:1.0];
// 2. 取消刚才执行的方法
[NSObject cancelPreviousPerformRequestsWithTarget:self];
  • NSInvocation其实就是将target/action以及这个action中要传递给target的参数这三者,在包装成一个对象。
NSMethodSignature *sig = [MyClass >instanceMethodSignatureForSele
ctor:@selector(doSomething:)];
NSInvocation *invocation = [NSInvocation >invocationWithMethodSig
nature:sig];
[invocation setTarget:someObject];
[invocation setSelector:@selector(doSomething:)];
[invocation setArgument:&anArgument atIndex:2];
NSTimer *timer = [NSTimer >scheduledTimerWithTimeInterval:1.0
                         invocation:invocation
                         repeats:YES];
  • 注意:在调用NSInvocationsetArgument:atIndex:方法时,要传递的参数至少要从 2 开始,由于是给objc_msgSend调用用的参数,在 0 的参数是对象自己,位置 1 的则是 selector.

在某个线程执行方法

  • -performSelectorOnMainThread:withObject:waitUntilDone:modes:
  • -performSelectorOnMainThread:withObject:waitUntilDone:
  • -performSelector:onThread:withObject:waitUntilDone:modes:
  • -performSelector:onThread:withObject:waitUntilDone:
  • -performSelectorInBackground:withObject:
  • 在子线程执行完任务后,可以通过-performSelectorOnMainThread:withObject:waitUntilDone:通知主线程执行完毕。

Array排序

  • 如果一个数组里面都是字符串的话,我们就可以使用compare:排序。
  • NSString的方法localizedCompare,会参考系统语言决定排序方式,比如:简体中文下用拼音排序,繁体中文下用笔画排序等等。
  • 可变数组用的:sortUsingSelector
  • 不可变数组用的:sortedArrayUsingSelector,会产生新的数组。
NSArray *sortedArray = [anArray sortedArrayUsingSelector:
                                @selector(localizedCompare:)];
  • 要求数组中的所有对象执行某个方法:makeObjectsPerformSelector:

代替if...elseswitch...case

  [super viewDidLoad];
   person * onject = [[person alloc]init];
   int condition = 0;
   switch(condition) {
       case 0:
           [onject run];
           break;
       case 1:
           [onject doSomeThing];
           break;
       default:
       break;
   }
  • 代替方法:[onject performSelector:NSSelectorFromString(@[@"run",@"doSomeThing"][condition])];
  • 我们可以使用NSStringFromSelector,将selector转换成NSString,反过来,也可以使用NSSelectorFromStringNSString转成selector

调用PrivateAPI

  • OC 没有真正所谓私有的方法,一个对象实现了哪些方法,即使没有 import头文件,我们都可以调用。可以通过performSelector:调用。但苹果不推荐,App Store上也会拒绝。

注意点:super调用performSelector:的区别

[super doSomthing];//代表的是调用父类的方法实现

[super performSelector:@selector(doSomething)] 
// 调用父类的 performSelector ,结果等同于 [self doSomething]

Refactor工具

  • 在要修改名字上面点击鼠标右键,选择Refactor中的Rename
  • 如果是通过performSelector:调用执行的方法,并不会把里面的 selector也换掉,只是会出现警告。

selectorOC所有魔法的开始

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,390评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,821评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,632评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,170评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,033评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,098评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,511评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,204评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,479评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,572评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,341评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,213评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,576评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,893评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,171评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,486评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,676评论 2 335

推荐阅读更多精彩内容