iOS 2019年6月学习记录

网络问题

HTTP

  1. get 和 post 的区别
  • get通过URL向Server获取数据,也可以在URL里向Server传递数据,传递的数据受限于URL的长度
  • post用于向Server传递数据并获得响应,数据通过body发送,数据量比get大
  • get参数直接写在URL里,安全性很差
  1. http2.0的特点
  • 二进制分帧在帧首部会预知收到的内容,格式固定。有10帧类型可供使用,解析的数据规范
  • 流:一次请求响应构成一个流,frame header里有streamID来表示,通过发送HEADER类型的帧启动一个流
  • 流量控制:通过发送WINDOW_UPDATE frame来协商流量
  • 优先级:可以为资源建立依赖关系,和优先级,确保资源请求的先后。
  • 推送:通过PUSH_PROMISE帧通知客户端,要进行推送
  • 首部压缩:重复使用两次请求相同的首部
  1. HTTP的POST的body体使用form-urlencoded和multipart/form-data的区别
    HTTP 协议是以 ASCII 码传输,HTTP 请求分为三个部分:请求行、请求头、消息主体。 POST 提交的数据必须放在消息主体(entity-body)中,但协议并没有规定数据必须使用什么编码方式,开发者完全可以自己决定消息主体的格式。服务端通常是根据请求头(headers)中的 Content-Type 字段来获知请求中的消息主体是用何种方式编码。Content-Type主要有四种:
    (1)application/x-www-form-urlencoded:如下图raw body会是name=homeway&key=nokey,在php中,通过$_POST就可以获得数组形式的数据


    (2)multipart/form-data:

    发送数据如下

    当文件太长,HTTP无法在一个包之内发送完毕,就需要分割数据。
    (3)application/json
    (4)text/xml

  2. HTTPS的加密原理
    在TCP和HTTP之间加了一层TLS层确保通信安全。在TCP握手完成之后会进行TLS握手。TLS的目标是为在它之上运行的应用提供三个基本服务:

    • 加密:通过对称秘钥进行数据加密
    • 身份验证:通过证书验证身份
    • 数据完整性校验:TLS每条记录都会被签上MAC,通过MAC验证消息的完整性

    TLS握手过程,整个过程2RTT

    • 协商加密套件服务端提供证书可供客户端验证身份,
    • 客户端验证完毕获取证书公钥,客户端生成一对对称秘钥用于加密数据,客户端用公钥把对称秘钥加密后传给服务端。
    • 验证消息完整性(通过MAC),服务端获取秘钥。
    • 客户端发送加密的“Finished消息”。

如何设计一个网络框架

  • URLSession layer:用一个manager来管理session,cachePolicy,securityPolicy,session回调代理
  • HTTP Client layer:封装http的各种请求
  • Business Layer:业务接口
    前两层在AFN已经实现。

iOS的网络缓存策略

TCP/IP

  1. TCP为什么是3次握手,4次挥手
    握手:客户端发送SYN,服务端确认发送ACK,客户端确认ACK+1
    挥手:客户端发送FIN,服务端ACK;服务端发送FIN,客服端
  2. 什么是socket,Socket建立网络连接的步骤?
    Socket 是对 TCP/IP 协议的封装,Socket 只是个接口不是协议,通过 Socket 我们才能使用 TCP/IP 协议,除了 TCP,也可以使用 UDP 协议来传递数据。
    socket连接步骤:
    (1) 服务器监听:服务器并不定位具体客户端的套接字,而是时刻处于监听状态;
    (2) 客户端请求:客户端的套接字要描述它要连接的服务器的套接字,提供地址和端口号,然后向服务器套接字提出连接请求;
    (3) 连接确认:当服务器套接字收到客户端套接字发来的请求后,就响应客户端套接字的请求,并建立一个新的线程,把服务器端的套接字的描述发给客户端。一旦客户端确认了此描述,就正式建立连接。而服务器套接字继续处于监听状态,继续接收其他客户端套接字的连接请求.
  3. TCP 流量控制

其他

  1. 项目中你是怎么处理网络速度慢、中断抖动等网络请求中的问题?
  2. 大文件离线下载怎么处理?会遇到哪些问题?又如何解决
  3. 用户需要上传和下载一个重要的资料文件,应该如何判断用户本次是否上传成功和下载成功了?
  4. 如果现在要实现一个下载功能, 你要如何设计。说说每个类具体做什么
  5. 平时如何实现网络请求, 一般返回的数据是什么格式, 如何解析..

OC Foundation

Block

  1. 为什么 block 里面还需要写一个 strong self,如果不写会怎么样?
    block里面用weak self防止recycle reference,如果block在执行的过程中外部self被释放,那么weak self将被置为nil。如果block执行时weak self已经为nil,那么block操作无效,不会crash;如果block访问weak self时,weak self还没有被置为nil,将会出现野指针问题,会crash。
  2. weak 的内部实现原理
    向__weak标示符标记的变量赋值会调用objc_storeWeak,这个函数会向weak_table注册一个key-value,key就是对象的地址,value就是weak变量地址数组。
  3. Block和函数指针的区别?
    函数指针指向函数的调用地址,block的结构体构造很像OC对象,在处理block的时候可以像对象那样对block进行内存管理,block结构体里有一个成员指针指向block代码块,这就是一个函数指针。
  4. 在block里面, 对数组执行添加操作, 这个数组需要声明成 __block吗
    对数组执行添加操作并不是改变数组的指针指向,所以数组变量没有被修改,这不需要block。
  5. 在block里面, 对NSInteger进行修改, 这个NSInteger是否需要声明成__blcok
    下面__block变量会被转换成一个结构体,当一个block使用这个变量时,block结构体构造函数会捕获__block变量结构体。从实现中可以看出__forwording指针指向__block 对象的内存。__forwording指针的功能是同步__block变量的变化,如果变量只在stack上__forwording指针指向自身,如果变量在stack上被copy heap上__forwording指针指向heap上。
__block int val = 10;

struct __Block_byref_val_0 { 
  void *__isa;
  __Block_byref_val_0 *__forwarding;
   int __flags;
  int __size;
  int val;
};

void (^blk)(void) = ^{val = 1;};
  struct __main_block_impl_0 {
  struct __block_impl impl;
  struct __main_block_desc_0* Desc;
  __Block_byref_val_0 *val;
  __main_block_impl_0(void *fp, struct __main_block_desc_0 *desc,
  __Block_byref_val_0 *_val, int flags=0) : val(_val->__forwarding) { impl.isa = &_NSConcreteStackBlock;
    impl.Flags = flags;
    impl.FuncPtr = fp;
    Desc = desc; }
};

(val->__forwarding->val) = 1; // forwarding指针指向的才是真正存值的地方。
  1. block本质是什么?
    block会被编译成一个结构体



    其中isa是block类型指针,FuncPtr是block代码块函数指针。
    根据isa指针,block一共有3种类型的block

    • _NSConcreteGlobalBlock 全局静态
    • _NSConcreteStackBlock 保存在栈中,出函数作用域就销毁
    • _NSConcreteMallocBlock 保存在堆中,retainCount == 0销毁
  2. block何时会被copy到heap上
    block和__block变量都是在stack上创建的。ARC模式下在大多数情况block会被copy到heap上,比如一个函数返回的block,在ARC模式下会被copy到heap上。以下几种情况编译器无法自动检测copy

    • block作为函数的参数传递,并且在函数内部没有对参数进行copy
    • Cocoa框架里的方法,比如使用的usingBlock
    • GCD接口

runtime

  1. 谈谈对runtime的理解
    runtime是支持OC动态特性的c运行时库。通过runtime可以动态的解析OC对象,进行消息发送和转发,反射机制,方法交换,关联对象等等。OC里的诸多特性都是通过runtime实现的。

  2. +load+initialize的区别
    (1)+initialize 是通过objc_msgSend进行调用的,所以有以下特点:

    • 如果子类没有实现+initialize,会调用父类的+initialize(所以父类的+initialize可能会被调用多次)
    • 如果分类实现了+initialize,就覆盖类本身的+initialize调用,也不能说是真正的覆盖,只不过是放到原类方 法的前面去了
    • 第一次用的时候才会调用,调用时机比+load
      (2)+load 是直接通过指针调用的,是在runtime加载时就调用,无论你用不用它都会调用
  3. 如何使用runtime hook一个class的某个方法,又如何hook某个instance的方法?hook的时候应该注意哪些?
    (1)method swizzling通过改变类的dispatch table让方法调用在运行时改变
    (2)通过class_getInstanceMethod获取实例方法,通过class_getClassMethod获取类方法
    (3)先直接为selector添加方法实现,如果不成功在进行方法交换
    (4)+load在class初次加载时被调用,+initialize在类或实例的方法第一次调用时被调用。因为method swizzling是影响全局状态的,所以应该尽早被加载,并且只加载一次。
    (5)dispatch_once防止多个线程同时调用+load,确保只swizzling一次。

@implementation UIViewController (Tracking)

+ (void)load {
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        Class class = [self class];

        SEL originalSelector = @selector(viewWillAppear:);
        SEL swizzledSelector = @selector(xxx_viewWillAppear:);

        Method originalMethod = class_getInstanceMethod(class, originalSelector);
        Method swizzledMethod = class_getInstanceMethod(class, swizzledSelector);

        // When swizzling a class method, use the following:
        // Class class = object_getClass((id)self);
        // ...
        // Method originalMethod = class_getClassMethod(class, originalSelector);
        // Method swizzledMethod = class_getClassMethod(class, swizzledSelector);

        BOOL didAddMethod =
            class_addMethod(class,
                originalSelector,
                method_getImplementation(swizzledMethod),
                method_getTypeEncoding(swizzledMethod));

        if (didAddMethod) {
            class_replaceMethod(class,
                swizzledSelector,
                method_getImplementation(originalMethod),
                method_getTypeEncoding(originalMethod));
        } else {
            method_exchangeImplementations(originalMethod, swizzledMethod);
        }
    });
}

#pragma mark - Method Swizzling

- (void)xxx_viewWillAppear:(BOOL)animated {
    [self xxx_viewWillAppear:animated];
    NSLog(@"viewWillAppear: %@", self);
}
  1. isa指针的作用?


  2. runtime如何通过selector找到对应的IMP地址
    a class (Class) maintains a dispatch table to resolve messages sent at runtime; each entry in the table is a method (Method), which keys a particular name, the selector (SEL), to an implementation (IMP), which is a pointer to an underlying C function.
    https://nshipster.com/method-swizzling/

  3. 消息转发机制?
    https://www.jianshu.com/p/f26413dec8f0 1.4
    当一个消息没有实现时,会抛出unrecognized selector异常,在这之前有3次补救机会
    resolve:为当前实例或类添加方法实现
    forwardingForTarget:把方法转发给一个对象
    forwardingForInvocation:把方法转发给多个对象

runloop

  1. 谈谈对runloop的理解
  2. RunLoop 的基本概念,它是怎么休眠的?
  3. Runloop和线程的关系?
  4. Runloop的作用?RunloopMode的原理?

AutoreleasePool

  1. autoreleasepool的使用场景和原理,什么时候释放

KVO & KVC

关于KVO的基础先参考https://www.jianshu.com/p/2b500fc772a9 第一部分

  1. KVO、Notification、delegate各自的优缺点,效率还有使用场景
    (1) delegate,网络回调,view事件代理等
  • 语法严格不易出错
  • 一个类可以实现多个代理
  • 逻辑流程好监控
  • 需要些大量代码
    (2)Notification,广播状态,全局通知
  • 消息中心发出消息,多个对象可以注册成观察者,方便解耦
  • 编译时不会检查通知是否被正确处理
  • 管理通知的生命周期
    (3)KVO,model-view同步
  • 通过key path方式观察对象的属性值
  • 接口烂
    delegate比NSNotification效率高,代理者需要给个结果给被代理的对象,根据结果做出行动,所以delegate模式解耦并不彻底。通知模式只管发出通知,不考虑接受者如何处理通知,这种通信是双盲的。delegate只是一对一,而这两个可以一对多。这两者也有各自的特点。
    https://www.cnblogs.com/tianglin/p/3552555.html
  1. 如何手动通知KVO
    先关闭自动通知,然后实现在setter方法里添加willChangeValueForKeydidChangeValueForKey
+ (BOOL)automaticallyNotifiesObserversForName
{ 
    return NO;
}
- (void)setName:(NSString *)name
{
     if (_name != name)  {
       [self willChangeValueForKey:@"name"];
      _name == name; 
      [self didChangeValueForKey:@"name"]; 
    }
}
  1. 如何实现KVO?
    https://tech.glowing.com/cn/implement-kvo/

  2. 在KVO中,他是怎么知道监听的对象发生了变化?
    会通过willChangeValueForKeydidChangeValueForKey方法发出通知。

  3. KVC机制是如何通过key找到value。
    通过先把key转换为getter方法,如果没有getter方法,就会去实例变量里找key对应的合适的变量名称(包括key, isKey, _key, _isKey),如果找不到就抛出异常。

其他

  1. 要用什么方式实现多继承?
    (a) 组合,像manager那样组合其他类的功能
    (b) Protocol,把共用的功能做成protocol
    (c) 消息转发,
    (d) category
    (e) NSProxy
  2. category和extension有什么区别
  3. NSObject, id区别
    id 表示void指针,可以指向任何对象,NSObject表示NSObject指针。在OC里面区别不大

UI

  1. 界面多个网络请求,如何处理刷新的?
    这考察的是一种是多个请求结束后统一操作,可以通过dispatch_semaphoredispatch_groupNSOperationQueue实现
    (https://cloud.tencent.com/developer/article/1334786)

  2. 说说事件响应链
    (1)iOS事件响应机制主要有两方面:事件分发和响应者链。事件分发是寻找第一响应者,APP接收到一个事件后UIKit会自动把事件转发给最合适的responder,这就是the first responder。响应者链用来确定响应事件的responder,如果the first responder不响应事件,那么UIKit就会把事件发送给next responder处理,直到事件被处理事件响应才结束。
    (2)通过hit-test机制递归寻找合适的响应者,把寻找过程中responder倒置就是响应者链。
    (3)所谓不合适包括以下几种情况

    • 响应点不在区域内
    • 响应者hidden = YES
    • 响应者alpha < 0.01
    • 响应者userInteractionEnabled = NO
  3. 对于image加载的优化方案有哪些
    (1)降采样使用缩略图
    (2)异步处理图片的解码
    (3)使用Image Asset Catalogs
    (4)图片解码后缓存

  4. 说说Cell重用原理
    当tableview创建时,当前页面上所有的cell会被创建。当滚动列表时,部分cell会移出窗口,移出的cell会被放入一个重用队列里等待重用。滚动时需要获取cell时,会先从重用队列里取cell,如果重用队列里没有cell才会创建新cell。有的tableview里有有多种类型的cell,这时需要identifier来标识,以便知道重用队列里的cell类型。重用cell有两种写法。

    • 判断型
    • 注册型
// 判断型
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
      //1.定义一个cell的标识为ID
      static NSString *ID = @"HomeCell";
      //2.从缓存池中取出cell
      UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:ID];
      //3.如果缓存池中没有cell
      if (cell == nil) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:ID];
    }
      //4.设置cell属性,
      cell.textLabel.text = [NSString stringWithFormat:@"%ld",(long)indexPath.row];
      return cell;
}

// 注册型,如果缓存池中没有,就根据注册创建新的cell,
[tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:ID]; // 也可以在xib里注册
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
      UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:ID];
      cell.textLabel.text = [NSString stringWithFormat:@"%ld",(long)indexPath.row];
      return cell;
}

https://www.jianshu.com/p/5b0e1ca9b673
https://www.jianshu.com/p/e00896730cca

  1. UITableView的相关优化
    UIView 优化可以从两个角度思考CPU和GPU
    1)CPU资源消耗原因
    • 对象创建:减少对象创建cell复用,尽量使用轻量对象如CALayer,对象延迟创建懒加载
    • 对象调整:UIView和CALayer修改属性时会通过消息转发机制临时创建方法,消耗较大。尽量避免在滚动时修改视图属性。
    • 对象销毁:
    • 布局计算与Autolayout:后台线程提前计算好视图布局、并且对视图布局进行缓存,尽量一次性计算好布局,不要在滚动时动态调整。对复杂页面不要进行Autolayout,应该自己计算frame。
    • 文本计算与渲染:CPU会计算文本宽高并绘制成bitmap,如果文本内容很多CPU压力会很大,使用TextKit或CoreText对文本进行异步绘制避免主线程压力过大
    • 图片解码与渲染 :图片在交给CALayer.contents 时会进行解码,并生成一张bitmap。为了避免主线程压力过大,可以把图片解码和渲染过程放在异步线程进行,并且进行图片缓存。使用SDWebImage,在drawRect里异步绘制。
      2)GPU 资源消耗原因,GPU渲染管道主要提供服务有GPU 能干的事情比较单一:接收提交的纹理(Texture)和顶点描述(三角形),应用变换(transform)、混合并渲染,然后输出到屏幕上。
    • 纹理的渲染:避免使用大图,使用缩率图。
    • 视图的混合:应当尽量减少视图数量和层次,并在不透明的视图里标明 opaque 属性以避免无用的 Alpha 通道合成。也可以把多个layer预先合成一个layer
    • 图形的生成:圆角,遮罩,阴影等会导致离屏渲染
  1. UIViewController 生命周期


    image.png
  2. 如果页面 A 跳转到 页面 B,A 的 viewDidDisappear 方法和 B 的 viewDidAppear 方法哪个先调用?
    在每一种转场下,appear 与 disappear 都有一些不一样的顺序,


  3. UIView和CALayer之间的关系

  • UIView继承自UIResponder,负责管理显示内容和响应事件,UIView显示内容是通过CALayer来实现的
  • CALayer主要负责内容展示,动画实现。
  • 每一个UIView都有一个CALayer属性,而UIView作为该CALayer的delegate可以实现显示、绘制、布局和动画方法。
@protocol CALayerDelegate <NSObject>
@optional
- (void)displayLayer:(CALayer *)layer;
- (void)drawLayer:(CALayer *)layer inContext:(CGContextRef)ctx;
- (void)layoutSublayersOfLayer:(CALayer *)layer;
- (nullable id<CAAction>)actionForLayer:(CALayer *)layer forKey:(NSString *)event;
  1. UIView、CoreAnimation和CoreGraphics的关系
    参考https://www.jianshu.com/p/509ef033cb1d iOS UI优化 第四小节

  2. 用过 TableView 吗,平时怎么解决 TableView 滑动卡顿问题的?
    同5 tableview的优化

Memory

  1. 介绍下内存的几大区域?
    (a) Stack:由系统存放函数参数和局部变量的值,系统管理内存分配和释放
    (b) Heap: 手动分配的内存空间,程序员负责管理内存
    (c) 全局区:存放全局变量和静态变量,由系统管理
    (d) 常量区:存放常量字符串,由系统管理
    (e) 代码区:存放二进制代码指令
  2. app内存你是如何分析的?

Thread

  1. 谈下iOS开发中知道的哪些锁? 哪个性能最差?SD和AFN使用的哪个? 一般开发中你最常用哪个? 哪个锁apple存在问题又是什么问题?
  • 常见的锁及其性能


    image.png
  • NSLock 内部封装了一个 pthread_mutex, NSCondition装了一个互斥锁和条件变量, @synchronized是一个 OC 层面的锁OC 在底层使用了一个互斥锁的数组。
  • AFN的URLSessionManager里使用了NSLock,在存取task delegate字典时使用的。SD里使用的dispatch_semaphore保证http headers和url operation存取的线程安全。
  • OSSpinLock会有优先级反转问题,由于spin lock是忙等机制,当低优先级线程拿到锁,高优先级线程进入忙等状态,低优先级线程锁不释放,高优先级就一直忙等。
  1. 使用atomic一定是线程安全的吗?
    使用atomic只能保证getter和setter操作的原子性,即当一个线程访问getter时其他线程不会访问该方法。如果此时有其他线程访进行setter方法,那么getter获得的值就不确定了。所以atomic并不是线程安全的。(或者说getter和setter使用的不是同一把锁)
  2. GCD原理
    (1)GCD是一个异步任务派发框架,提供了系统级线程管理服务。
    (2)GCD中队列分为串行队列和并行队列。GCD提供5个系统队列,一个主队列和4个不同优先级的后台队列
  3. GCD控制线程数量和任务依
    dispatch_semaphore, dispatch_group

Third Framework

SDWebImage

  1. 分析下SDWebImage
  • SDMemoryCache继承自NSCache并且遵循SDMemoryCache协议,以key-value形式存取信息
  1. SDWebImage 的最大并发数
  • SDWebImageDownloader里用NSOperation和NSOperationQueue来管理下载任务。
  • 用SDWebImageDownloaderConfig存储downloader的各种设置,其中maxConcurrentDownloads表示最大并发数,默认的config使用的是6
  • 配置: config_downloadQueue.maxConcurrentOperationCount = _config.maxConcurrentDownloads;
  1. SDWebImage是如何区分不同格式的图像的
    根据文件二进制编码的第一字节确定图片类型, 在NSData+ImageContentType中有如下实现。在https://www.garykessler.net/library/file_sigs.html 网页里可以找到各种类型文件的头部字节。
+ (SDImageFormat)sd_imageFormatForImageData:(nullable NSData *)data {
    if (!data) {
        return SDImageFormatUndefined;
    }    
    // File signatures table: http://www.garykessler.net/library/file_sigs.html
    uint8_t c;
    [data getBytes:&c length:1];
    switch (c) {
        case 0xFF:
            return SDImageFormatJPEG;
        case 0x89:
            return SDImageFormatPNG;
        case 0x47:
            return SDImageFormatGIF;
        case 0x49:
        case 0x4D:
            return SDImageFormatTIFF;
        case 0x52: ...
            break;
        }
        case 0x00:...
            break;
        }
    }
    return SDImageFormatUndefined;
}
  1. 如何保证UI操作放在主线程执行
    通过dispatch_main_async_safe保证在主线程执行,可以减少线程切换。可以通过非主队列派发任务到主线程执行,因此用isMainThread方式判断并不安全。
#define DISPATCH_CURRENT_QUEUE_LABEL NULL
dispatch_queue_get_label(dispatch_queue_t _Nullable queue); // 获取queue的label,如果传如NULL则获取当前queue的label

#ifndef dispatch_main_async_safe
#define dispatch_main_async_safe(block)\
    if (dispatch_queue_get_label(DISPATCH_CURRENT_QUEUE_LABEL) == dispatch_queue_get_label(dispatch_get_main_queue())) {\
        block();\
    } else {\
        dispatch_async(dispatch_get_main_queue(), block);\
    }
#endif
  1. 如何保证SDImageCache的线程安全
  • SDMemoryCache继承者 NSCacheNSCache是线程安全的
  • SDDiskCache使用NSFileManger管理磁盘文件的创建和删除文件,用NSData读取文件。磁盘缓存相关操作会被放入ioQueue串行队列里保证线程安全。
  1. 使用SDWebImage内存爆涨的问题遇到没,怎么解决?

RAC

  1. ReactiveCocoa(RAC)如何防止UIButton短时间内多次重复点击,大概思路?
    结合RACCommand使用。
    https://www.zybuluo.com/myron-lee/note/430599
  2. RAC中数据视图绑定方式
  • RACSignal: 1v1单向数据流
  • RACMulticastConnection: 1v多单向数据流
  • RACChannel: 1v1双向数据流
  1. RACChannel如何实现双向绑定
  2. RACCommand如何实现
  3. RAC内存管理
    https://www.jianshu.com/p/d774d4680c5d

AFNetworking

  1. AFNetworking是否支持ipv6?
  2. 与 NSURLConnection 相比,NSURLsession 改进哪些?

YYKit

  1. YYAsyncLayer如何异步绘制?

CocoaPod

  1. 熟悉 CocoaPods 么?能大概讲一下工作原理么?
    cocoapods主要由依赖解析器、下载工具和Xcode工程管理工具这三个组件构成,我们创建pod时把pod的描述信息放到podspec文件里,在使用的时候通过podfile指定依赖关系,cocoapods就会自动对依赖关系进行解析,并下载对应的源码,配置Pods工程。

WorkFlow

  1. 测试都有哪些方式?优缺点呢?

Common

NSURLSession

  1. session和cookie
    HTTP协议本身是无状态的,在进行连接-请求-响应-关闭之后就结束了。 cookie机制采用的是在客户端保持状态的方案,而session机制采用的是在服务器端保持状态的方案。同时我们也看到,由于采用服务器端保持状态的方案在客户端也需要保存一个标识,所以session机制可能需要借助于cookie机制来达到保存标识的目的,但实际上它还有其他选择。
    理解HTTP session原理及应用

  2. URLSession类型

  • shareSession: 使用当前全局设置的NSURLCache, NSHTTPCookieStorage and NSURLCredentialStorage
  • Default Sessions: 采用defaultSessionConfiguration,
  • Ephemeral sessions: 采用ephemeralSessionConfiguration,不允许 write caches, cookies, or credentials to disk.
  • Background Sessions: APP不运行的时候,开启后台上传或下载任务
  1. URL Session Tasks类型
  • Data tasks:使用NSData对象接发数据,通常用于短小高频请求
  • Upload tasks:通常以文件的形式发送数据,支持后台上传
  • Download tasks:支持文件形式接收数据,支持后台上传下载
  1. URL sessions also support canceling, restarting, resuming, and suspending tasks, and provide the ability to resume suspended, canceled, or failed downloads where they left off.
    task可以被cancel,也可以被suspend。调用resume,task会重启任务。

NSURLSession Document

  1. 缓存策略
  • 为每个request设置requestCachePolicy
  • 在sessionConfiguration里设置requestCachePolicy
typedef NS_ENUM(NSUInteger, NSURLRequestCachePolicy)
{
    NSURLRequestUseProtocolCachePolicy = 0,  // 使用缓存的方式由 Cache-Control 决定

    NSURLRequestReloadIgnoringLocalCacheData = 1,
    NSURLRequestReloadIgnoringLocalAndRemoteCacheData = 4, // Unimplemented
    NSURLRequestReloadIgnoringCacheData = NSURLRequestReloadIgnoringLocalCacheData,

    NSURLRequestReturnCacheDataElseLoad = 2,
    NSURLRequestReturnCacheDataDontLoad = 3,

    NSURLRequestReloadRevalidatingCacheData = 5, // Unimplemented
};
  • 设置全局cache大小
  • 在sessionConfiguration里设置cache大小
NSURLCache *urlCache = [[NSURLCache alloc] initWithMemoryCapacity:1*1024*1024 diskCapacity:30*1024*1024 diskPath:nil];
NSURLCache.sharedURLCache = urlCache;

NSURLSessionConfiguration *defaultConfiguration = [NSURLSessionConfiguration defaultSessionConfiguration];
defaultConfiguration.URLCache = urlCache;

Crash

  1. 导致crash的场景
    (1)iOS策略

    • 低内存
    • watchdog
    • 用户强退
      (2)代码bug
    • 数组越界
    • KVC,给不存在的key设置value
    • 访问野指针(EXC_BAD_ACCESS)
    • 未识别selector
    • 多线程,死锁,子线程跟新UI,
    • Socket长连接,进入后台没有关闭
      https://www.jishuwen.com/d/2del#tuit
  2. crash的收集和定位bug的方式谈下
    (1)简介
    先在最底层产生Mach异常;Mach异常在host层被转换为相应的Unix Signal; 在OC层如果有对应的NSException(OC异常),就转换成OC异常,OC异常可以在OC层得到处理。
    (2)捕获crash

    • try catch 捕获OC异常,APPLE不建议这么做。所以通常OC层中未被捕获的异常,通过注册NSUncaughtExceptionHandler捕获异常信息
    • OC中层不能转换的Mach异常,利用Unix标准的signal机制,注册SIGABRT, SIGBUS, SIGSEGV等信号发生时的处理函数。
      (3)崩溃日志
    • Xcode里获取崩溃日志
    • 三方获取崩溃日志
    • 终端获取崩溃日志
      通过查看日志里的Exception type、Exception code和堆栈信息定位bug。在Xcode里可以通过全局断点定位bug。
      https://hanson647.com/2018/07/25/iOS%E4%B8%AD%E7%9A%84crash/
  3. dSYM你是如何分析的?
    dSYM是符号表,保存了地址和符号之间的映射关系。通过UUID可以找到对应的dSYM,使用符号表工具,输入内存地址可以得到对应的符号。

  4. 0x8badf00d表示是什么?
    eat bad food,watchdog长时间卡顿

  5. 如何定位野指针bug
    (1)Enable Scribble: Fill allocated memory with 0xAA and deallocated memory with 0x55.
    Scribble will make it rather obvious that you're using a memory block after it's free'd by overwriting any data that used to be in the memory block upon free.
    启用数据写入:对象释放时,所用内存并没有完全被擦除,仍有旧对象部分数据可用,如果不使用Zombie调试,App可能不会直接crash。对付这种情况,其实很简单,可以在对象内存释放时写入无意义数据分配的内存写入数据0xAA,释放的内存写入0x55。有些内存块已经被释放时,可以通过对数据进行重写让你继续使用内存块。
    (2)僵尸对象(Zombie Objects):在对象释放(retainCount 为0)时,使用一个内置的Zombie对象,替代原来被释放的对象。无论向该对象发送什么消息(函数调用),都会触发异常,抛出调试信息。

其他

  1. framework是动态链接库还是静态链接库,和.a的区别是什么
  • 库(Library)说白了就是一段编译好的二进制代码,加上头文件就可以供别人使用。
  • 静态库即静态链接库(Windows 下的 .lib,Linux 和 Mac 下的 .a),动态库即动态链接库(Windows 下的 .dll,Linux 下的 .so,Mac 下的 .dylib/.tbd)
  • Framework 实际上是一种打包方式,将库的二进制文件,头文件和有关的资源文件打包到一起,方便管理和分发。
    https://www.jianshu.com/p/13bf46df9387
  1. app的性能优化,都有哪些?优化你是从哪几方面着手?
    CPU,Memory,UI,Networking
  2. 是否了解设计模式, 用过哪些?
  • 观察者模式
  • 工厂模式,类族
  • 组合模式,manager
  • 状态机,NSOperation
  1. MVC里面, View怎么通知到Model?
    原则上view和model不能直接通信,需要通过controller来通信。controller同时持有view和model,model通过KVO或通知向controller发信息,view通过delegate和target-action与controller通信。


  2. 做过最大的项目主要难点在哪里?

  3. MVC具有什么样的优势,各个模块之间怎么通信,比如点击 Button 后 怎么通知 Model?
    同 4,点击button后,通过target-action,controller处理点击事件更新model。

  4. CoreData的使用,如何处理多线程问题?

  5. 如何组件化解耦的?
    模块之间互相依赖,代码耦合性强,可维护性差,为了解决这个问题,从以下几个方面着手:
    (1)分层,把整个项目分为,分层的原则是底层不依赖于上层,上层公共部分下沉到底层

  6. 怎么防止别人反编译你的app?

  7. 代码文件编译生成过程,做了哪些事情;build过程
    针对工程中的每个 target,Xcode 都会执行一系列的操作,将相关的源码,根据所选定的平台,转换为机器可读的二进制文件。
    (1)依赖target处理:先处理pch预编译头文件,然后编译生成不同架构的.a文件并合并
    (2)编译项目代码
    (3)链接
    (4)将静态资源copy到app bundle中
    (5)code sign,packaging
    https://objccn.io/issue-6-1/
    [https://hanson647.com/2018/01/22/2017/iOS%E7%BC%96%E8%AF%91%E8%BF%87%E7%A8%8B%E8%AF%A6%E8%A7%A3/]

  8. app启动做了哪些事情;app启动优化

  1. 说说你项目中常用到的调试技巧?
  2. 如何把异步线程转换成同步任务进行单元测试?
  3. UIView和NSObject这两个类,所有里面的方法和原理都需要了解一下。

算法与数据结构

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

推荐阅读更多精彩内容

  • Swift1> Swift和OC的区别1.1> Swift没有地址/指针的概念1.2> 泛型1.3> 类型严谨 对...
    cosWriter阅读 11,065评论 1 32
  • 史上最全的iOS面试题及答案 iOS面试小贴士———————————————回答好下面的足够了----------...
    Style_伟阅读 2,338评论 0 35
  • 最全的iOS面试题及答案 iOS面试小贴士 ———————————————回答好下面的足够了-----------...
    zweic阅读 2,669评论 0 73
  • 2019年高考已落下帷幕,而高考掀起的各样浪潮却还在翻腾。 且不说有考生在场外等到考试时间已过45分钟还没入场,也...
    冷兰子阅读 855评论 0 7
  • 每周一次的KT足球又和我们见面了,不是阳光的吉米教练,也不是帅气的丁丁教练 而是漂亮的子恒教练给我们带来精彩的“带...
    马超河北清河县马屯小学阅读 244评论 3 5