美文网首页
招聘靠谱的ios下

招聘靠谱的ios下

作者: 纳兰沫 | 来源:发表于2019-01-16 15:26 被阅读8次

    非作者原著 来自摘抄

    参考文献

    招聘靠谱的ios下

    _objc_msgForward 函数是做什么的 直接调用它将会发生什么

    _objc_msgForward是IMP类型 用于消息转发 当向一个对象发送一条消息 但它
    并没有实现的时候 _objc_msgForward会尝试做消息转发
    
    objc_msgSend 在"消息转发"中的作用 首先在Class中的缓存查找IMP(没缓存则
    初始化缓存) 如果没有找到, 则向父类的Class查找 如果一直查找到根类仍没有
    实现 则用_objc_msgForward函数指针代替IMP 最后 执行这个IMP
    
    1. 调用"resolveInstanceMethod:" 方法(或resolveClassMethod:) 允许用户
    在此时为该Class动态添加实现 如果有实现了 则调用并返回YES 那么重现开始
    objc_msgSend流程 这一次对象会响应这个选择器 一般是因为它已经调用过
    class_addMethod 如果仍没有实现 继续下面的动作
    2. 调用"forwardingTargetForSelector:" 方法 尝试找到一个能响应该消息的
    对象 如果获取到 则直接把消息转发给它 返回非nil对象 否则返回nil 继续下面
    的动作 注意 "这里不要返回self 否则会形成死循环"
    3. 调用"methodSignatureForSelector: "方法 尝试获取一个方法签名 如果获取
    不到 则直接调用doesNotRecognizeSelecor 抛出异常 如果能获取 则返回非
    nil 创建一个NSInvocation并传给forwardInvocation
    4. 调用"forwardInvocation:" 方法 将第三步获取到的方法前面包装成
    Invocation传入 如何处理就在这里面了 并返回非nil
    5. 调用"doesNotRecognizeSelector" 默认的实现是抛出异常 如果第三步没能获
    取一个方法签名 执行该步骤
    
    _objc_msgForward隶属 C 语言,有三个参数
    一旦调用_objc_msgForward 将跳过查找IMP的过程 直接触发"消息转发"
    如果调用了_objc_msgForward 即使这个对象确实已经实现了这个方法 它也会告诉objc_msgSend 我没有在这个对象里面找到这个方法的实现

    runtime如何实现weak变量的自动置nil 不理解

    能否向编译后得到的类中增加实例变量 能否向运行时创建的类中添加实例变量

    不能向编译后得到的类中增加实例变量
    能向运行时创建的类中添加实例变量
    
     - 因为编译后的类已经注册在runtime中 类结构中的objc_ivar_list 实例变量的
    链表和 instance_size 实例变量的内存大小已经确定 同时runtime会调用
    class_setIvarLayout 或 class_setWeakIvarLayout 来处理 strong weak引用 
    所以 不能向存在的类中添加实例变量
    
    - 运行时创建的类是可以添加实例变量 调用class_addIvar函数 但是得在调用
    objc_allocateClassPair之后 objc_registerClassPair之前  原理同上
    

    runloop和线程有什么关系

    RunLoop 是线程的基础架构部分 每个线程 包括程序的主线程都有与之相应的
    run loop对象
    主线程的run loop默认是启动的
    其他线程的run loop默认是没有启动的
    

    runloop 的mode作用是什么

    mode 主要是用来指定时间在运行循环中的优先级的 分为
    -  NSDefaultRunLoopMode 默认 空闲状态
    -  UITrackingRunLoopMode ScrollView 滑动时
    -  UIInitializationRunLoopMode 启动时
    -  NSRunLoopCommonModes (kCFRunLoopCommonModes) mode集合
    

    以 +scheduledTimerWithTimeInterval... 的方式触发的timer 在滑动列表时 timer会暂停回调 为什么 如何解决

    - RunLoop 只能运行在一种mode下 如果要换mode  当前的loop也需要停下重新启动
    新的 利用这个机制 ScrollView 滚动过程中NSDefaultRunLoopMode的mode会切换
    到UITrackingRunLoopMode来保证ScrollView的流畅滑动 只能在
    NSDefaultRunLoopMode模式下处理的事件会影响ScrollView的滑动
    - 如果我们把一个NSTimer对象以NSDefaultRunLoopMode(kCFRunLoopDefault
    Mode)添加到主运行循环中的时候, ScrollView滚动过程中会因为mode的切换,而
    导致NSTimer将不再被调度
    
    //将timer添加到NSDefaultRunLoopMode中
    [NSTimer scheduledTimerWithTimeInterval:1.0
         target:self
         selector:@selector(timerTick:)
         userInfo:nil
         repeats:YES];
    //然后再添加到NSRunLoopCommonModes里
    NSTimer *timer = [NSTimer timerWithTimeInterval:1.0
         target:self
         selector:@selector(timerTick:)
         userInfo:nil
         repeats:YES];
    [[NSRunLoop currentRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];
    

    猜想runLoop内部是如何实现的

    一个线程一次只能执行一个任务 执行完成后线程就会退出
    
    // 
    // http://weibo.com/luohanchenyilong/ (微博@iOS程序犭袁)
    // https://github.com/ChenYilong
    int main(int argc, char * argv[]) {
     //程序一直运行状态
     while (AppIsRunning) {
          //睡眠状态,等待唤醒事件
          id whoWakesMe = SleepForWakingUp();
          //得到唤醒事件
          id event = GetEvent(whoWakesMe);
          //开始处理事件
          HandleEvent(event);
     }
     return 0;
    }
    

    objc使用什么机制管理对象内存

    通过retainCount 的机制来决定对象是否需要释放 每次RunLoop的时候 都会检查
    对象的retainCount 如果retainCount为0 说明该对象没有地方需要继续使用了 可
    以释放了
    

    ARC 通过什么方式帮助开发者管理内存

    在编译期和运行期两部分共同帮助开发者管理内存
    在编译器 ARC用的是更底层的C接口实现retain/release/autorelease 性能更好 
    同时对同一上下文的同一对象的成对retain/release 操作进行优化 
    

    不手动指定autoreleasepool的前提下,一个autorealese对象在什么时刻释放?(比如在一个vc的viewDidLoad中创建)

    分两种情况  手动干预是否时机  系统自动去释放
    1. 手动干预释放时机 --- 指定autoreleasepool 就是所谓的  当前作用域大括号
    结束时释放
    2. 系统自动去释放 --- 不手动指定autoreleasepool
    

    Autorelease对象出了作用域之后 会被添加到最近一次创建的自动释放池中 并会在当前的runloop迭代结束时释放
    [站外图片上传中...(image-14b985-1547623556024)]
    在一个完整的运行循环结束之前 会倾倒释放池中的对象 会被销毁
    运行循环检测到事件并启动后 就会创建自动释放池

    @autoreleasepool 当自动释放池被销毁或者耗尽时,会向自动释放池中的所有对象
    发送 release 消息,释放自动释放池中的所有对象。
    
    如果在一个vc的viewDidLoad中创建一个 Autorelease对象,那么该对象会在
     viewDidAppear 方法执行前就被销毁了。
    

    BAD_ACCESS 在什么情况下出现

    访问了悬垂指针 比如对一个已经释放的对象执行了release 访问已经释放对象的
    成员变量或者发消息 死循环
    

    苹果如何实现autoreleasepool的

    autoreleasepool 以一个队列数组的形式实现 主要通过下列三个函数完成
     - objc_autoreleasepoolPush
     - objc_autoreleasepoolPop
     - objc_autorelease
    

    [站外图片上传中...(image-210195-1547623556024)]

    使用block时什么情况下回发生引用循环 如何解决

    一个对象中强引用了block 在block中又强引用了该对象 就会发生循环引用
    
    解决办法就是将该对象使用_weak或者_block修饰符修饰后再在block中使用
     - id weak weakSelf = self 或者 weak __typeof(& *self)weakSelf = self该方法可以设置宏
     - id _block weakSelf  = self;
    或者将其中一方强制置空 xxx = nil
    

    在block 内如何修改block外部变量

    Block 不允许修改外部变量的值
    这里所说的外部变量的值 指的是栈中指针的内存地址  __block所起的到作用就是只
    要观察到该变量被block所持有 就将"外部变量"在栈中的内存地址放到了堆中 进而
    在block内部也可以修改外部变量的值
    

    Block不允许修改外部变量的值 这里所说的外部变量的值 指的是栈中指针的内存地址 栈区是红灯区 堆区才是绿灯区

    使用系统的某些block api (如UIView的block版本写动画时) 是否考虑引用循环问题

    系统的某些block api中  UIView的block版本写动画时不需要考虑 但也有一些api
    需要考虑
    
    单向的强引用 没有问题
    [UIView animateWithDuration:duration animations:^{ [self.superview layoutIfNeeded]; }]; 
    [[NSOperationQueue mainQueue] addOperationWithBlock:^{ self.someProperty = xyz; }]; 
    [[NSNotificationCenter defaultCenter] addObserverForName:@"someNotification" 
                                                     object:nil 
                              queue:[NSOperationQueue mainQueue]
                                                 usingBlock:^(NSNotification * notification) {
                                                       self.someProperty = xyz; }]; 
    
    
    强引用
    __weak __typeof__(self) weakSelf = self;
    dispatch_group_async(_operationsGroup, _operationsQueue, ^
    {
    __typeof__(self) strongSelf = weakSelf;
    [strongSelf doSomething];
    [strongSelf doSomethingElse];
    } );
    
     __weak __typeof__(self) weakSelf = self;
     _observer = [[NSNotificationCenter defaultCenter] addObserverForName:@"testKey"
                                                                   object:nil
                                                                    queue:nil
                                                               usingBlock:^(NSNotification *note) {
         __typeof__(self) strongSelf = weakSelf;
         [strongSelf dismissModalViewControllerAnimated:YES];
     }];
    

    GCD队列

     - 串行队列 Serial Dispatch Queue
    - 并行队列 Concurrent Dispatch Queue
    

    dispatch_barrier_async 作用

    必须搭配自定义并发队列 dispatch_queue_t 使用 不能使用dispatch_get_global_queue 否则 dispatch_barrier_async的作用会和dispatch_async 的作用一模一样

    苹果为什么废弃 dispatch_get_current_queue

    dispatch_get_current_queue 容易造成死锁

    addObserver:forKeyPath:options:context 各个参数的作用分别是什么 observer中需要实现哪个方法才能获得KVO回调

    // 添加键值观察
    /*
    1 观察者,负责处理监听事件的对象
    2 观察的属性
    3 观察的选项
    4 上下文
    */
    [self.person addObserver:self forKeyPath:@"name" options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld context:@"Person Name"];
    

    observer中需要实现的方法

    ```source-objc
    // 所有的 kvo 监听到事件,都会调用此方法
    /*
     1\. 观察的属性
     2\. 观察的对象
     3\. change 属性变化字典(新/旧)
     4\. 上下文,与监听的时候传递的一致
     */
    - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context;
    

    如何手动触发一个value的KVO

    键值观察通知依赖于 NSObject 的两个方法: willChangeValueForKey: 和 
    didChangevlueForKey:
    

    KVC的keyPath中的集合运算符如何使用?

    1.  必须用在集合对象上或普通对象的集合属性上
    2.  简单集合运算符有@avg, @count , @max , @min ,@sum,
    3.  格式 @"@sum.age"或 @"集合属性[.@max.age](mailto:.@max.age)"
    

    KVC和KVO的keyPath一定是属性么?

    KVC 支持实例变量,KVO 只能手动支持手动设定实例变量的KVO实现监听

    50. 如何关闭默认的KVO的默认实现,并进入自定义的KVO实现?

    请参考:

    1. 《如何自己动手实现 KVO》
    2. KVO for manually implemented properties

    apple用什么方式实现对一个对象的KVO

    当你观察一个对象时,一个新的类会被动态创建。这个类继承自该对象的原本的类,并重写了被观察属性的 setter 方法。重写的 setter 方法会负责在调用原 setter 方法之前和之后,通知所有观察对象:值的更改。最后通过 isa 混写(isa-swizzling) 把这个对象的 isa 指针 ( isa 指针告诉 Runtime 系统这个对象的类是什么 ) 指向这个新创建的子类,对象就神奇的变成了新创建的子类的实例


    手动触发”的使用场景是什么?一般我们只在希望能控制“回调的调用时机”时才会这么做。
    而“回调的调用时机”就是在你调用 didChangeValueForKey: 方法时

    IBOutlet连出来的视图属性为什么可以被设置成weak?

    因为既然有外链那么视图在xib或者stotyboard肯定存在 视图已经对它有一个强引用
    

    相关文章

      网友评论

          本文标题:招聘靠谱的ios下

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