iOS (四)

1.数据存储

详见数据存储文章

2. volatile

一个定义为 volatile 的变量是说这变量可能会被意想不到地改变,这样,编译器就不会去假设这个变量的值了。

3.常驻线程

RunLoop最后部分

4.编程题

3个线程顺序打印1-100

- (void)print0_100 {
    
    __block int i = 0;
    dispatch_queue_t queueA = dispatch_queue_create("queue a", DISPATCH_QUEUE_CONCURRENT);
    dispatch_queue_t queueB = dispatch_queue_create("queue b", DISPATCH_QUEUE_CONCURRENT);
    dispatch_queue_t queueC = dispatch_queue_create("queue c", DISPATCH_QUEUE_CONCURRENT);

    NSCondition *condition = [[NSCondition alloc] init];
    
    dispatch_async(queueA, ^{
        while (1) {
            [condition lock];
            while (i%3 != 0) {
                [condition wait];
            }
            if (i > 100) {
                [condition unlock];
                return;
            }
            NSLog(@"A ==== i = %d",i);
            I++;
            [condition broadcast];
            [condition unlock];
        }
    });
    
    dispatch_async(queueB, ^{
        while (1) {
            [condition lock];
            while (i%3 != 1) {
                [condition wait];
            }
            if (i > 100) {
                [condition unlock];
                return;
            }
            NSLog(@"B ==== i = %d",i);
            I++;
            [condition broadcast];
            [condition unlock];
        }
    });

    dispatch_async(queueC, ^{
        while (1) {
            [condition lock];
            while (i%3 != 2) {
                [condition wait];
            }
            if (i > 100) {
                [condition unlock];
                return;
            }
            NSLog(@"C ==== i = %d",i);
            I++;
            [condition broadcast];
            [condition unlock];
        }
    });

}

5.NSThread 任务如何在执行过程中让他终止

//监测当前线程是否被取消过,如果被取消了,则该线程退出。在线程里面检测取消的标记,然后执行退出
if ([[NSThread currentThread] isCancelled])
{
[NSThread exit];
}

6.NSOperation 是如何终止/取消任务的

正在执行的任务,NSOperation 也是不能取消的。

7.多线程,异步执行(async)一个 performSelector 会执行么?如果加上 afterDelay

performSelector 会执行,afterDelay 不会执行;
原因 performSelector 只是单纯的直接调用某函数,afterDelay 是在该子线程执行一个 NSTimer,注意一点:子线程中的 runloop 默认是没有启动的状态,要想 afterDelay 生效,要 runloop 在线程有事务的状态下跑起来,所以需要执行 [[NSRunLoop currentRunLoop] run]

8.isa 指针里面都存了什么,32和64位分别讲一下

在ARM 32 位的时候,isa 的类型是 Class 类型的,直接存储着实例对象或者类对象的地址;
在ARM 64 结构下,isa 的类型变成了共用体(union),使用了位域去存储更多信息。

9.NSMutableArray 实现原理

NSMutableArray 是一个类族,[[NSMutableArray new] class] 打印出来的是 __NSArrayM
通过 class-dump 逆向查看 __NSArrayM 里面的比较重要的成员变量:
_used : 计数
_list : 缓冲区指针
_size : 缓冲区大小
_offset : 缓冲区中的数组的第一个元素的索引

过程原理,OC 数组比 C 语言里的数组用了稍微复杂一点的环形缓冲区
环形缓冲区的特点是:在大多数情况下,除非缓冲区满了,否则不需要频繁分配内存。
并且 NSMutableArray 做到了如果我们在中间进行插入或者删除,只会移动最少的一边的元素。
来看一下 增、删、改、查。
查询:
-(void)objectAtIndex:(NSIteger)index; 为例子

-(void)objectAtIndex:(NSIteger)index
       {
         NSIteger originalOffset = _offset  + index;
         NSIteger reallOffset = originalOffset - ( _size > originalOffset ? 0 : size );
 
         Return  _list[ reallOffset ];
        }

分析:分两种情况,需比较 _size_offset + index 的大小
(1)A: 当 _size >= _offset + index 时:


(2)当 _size < _offset + index时:

10.自旋锁和互斥锁怎么选择

自旋锁:

  1. 时间短
  2. 加锁的代码(临界区)经常被调用,但竞争情况很少发生
  3. CPU资源不紧张
  4. 多核
    互斥锁:
  5. 时间长
  6. 单核
  7. 临界区有IO操作
  8. 临界区代码复杂或者循环量大
  9. 临界区竞争非常激烈

11.atomic@synchroize 原理

atomic 原子性,settergetter 加了自旋锁(实则是互斥锁)。@synchronized 是一个互斥递归锁。

什么是自旋锁呢?
锁用于解决线程争夺资源的问题,一般分为两种,自旋锁(spin)和互斥锁(mutex)。
互斥锁可以解释为线程获取锁,发现锁被占用,就向系统申请锁空闲时唤醒他并立刻休眠。互斥锁加锁的时候,等待锁的线程处于休眠状态,不会占用 CPU 的资源
自旋锁比较简单,当线程发现锁被占用时,会不断循环判断锁的状态,直到获取。自旋锁加锁的时候,等待锁的线程处于忙等状态,并且占用着 CPU 的资源。
原子操作的颗粒度最小,只限于读写,对于性能的要求很高,如果使用了互斥锁势必在切换线程上耗费大量资源。相比之下,由于读写操作耗时比较小,能够在一个时间片内完成,自旋更适合这个场景。

原来系统中自旋锁已经全部改为互斥锁实现了,只是名称一直没有更改。
为了修复优先级反转的问题,苹果也只能放弃使用自旋锁,改用优化了性能的 os_unfair_lock,实际测试两者的效率差不多。
os_unfair_lock 用于取代不安全的 OSSpinLock ,从iOS10开始才支持
从底层调用看,等待 os_unfair_lock 锁的线程会处于休眠状态,并非忙等

12.HTTP 请求方法种类有哪些

方法 说明
GET 获取资源
POST 传输实体主体
PUT 传输文件
HEAD 获得报文首部
DELETE 删除文件
OPTION 询问支持的方法
TRACE 追踪路径
CONNECT 要求用隧道协议连接代理
LINK 建立和资源之间的联系

13.造成 tableView 卡顿的原因有哪些

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 面试题 一个NSObject对象占用多少内存?实际上分配了16个字节的存储空间给NSObject对象真正有使用的空...
    AngeloD阅读 561评论 0 0
  • iOS多线程 iOS中多线程的方案?有什么优缺点? 技术方案简介语言线程生命周期使用频率pthread1.一套通用...
    喜歡w阅读 482评论 0 0
  • UIKit和Foundation的线程安全 在UIKit和Foundation中,有很多操作都是非线程安全的,比如...
    Jason1226阅读 572评论 0 0
  • 1、TCP连接的三次握手过程? 第一次握手:客户端发送 syn 包(syn=j)到服务器,并进入 SYN_SEND...
    异乡人_4f2a阅读 675评论 0 2
  • 作者:南泽1链接:https://zhuanlan.zhihu.com/p/146761745来源:知乎著作权归作...
    反复练习的阿离很笨吧阅读 855评论 0 0