美文网首页读书笔记Objective-CiOS 杂谈
(2018年3月22号重编)kkbox-ios-dev笔记(一)

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

作者: 百草纪 | 来源:发表于2017-02-13 20:55 被阅读203次

    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所有魔法的开始

    相关文章

      网友评论

        本文标题:(2018年3月22号重编)kkbox-ios-dev笔记(一)

        本文链接:https://www.haomeiwen.com/subject/wxmtwttx.html