给即将失业的iOS从业者整理的OC基础知识

384 阅读10分钟

1.与OC比较.Swift有什么优点?

Swift 是一门新型语言,借鉴了JS,Python,C#,Ruby等语言特性,看上去偏脚本化,Swift 仍支持 cocoa touch 框架

优点:

  1. Swift更加安全,它是类型安全的语言。
  2. Swift容易阅读,语法和文件结构简易化。
  3. Swift更易于维护,文件分离后结构更清晰。
  4. Swift代码更少,简洁的语法,可以省去大量冗余代码
  5. Swift速度更快,运算性能更高。

2. delegate(代理,委托)

委托是协议的一种,顾名思义,就是委托他人帮自己去做什么事。

delegate:

  1. 非常严格的语法。所有将听到的事件必须是在delegate协议中有清晰的定义,语法清晰,易读;
  2. 如果delegate中的一个方法没有实现那么就会出现编译警告/错误
  3. 在释放代理对象时,需要小心的将delegate改为nil。一旦设定失败,那么调用释放对象的方法将会出现内存crash

3.Notification(通知)

在IOS应用开发中有一个”Notification Center“的概念。它是一个单例对象,允许当事件发生时通知一些对象。

notification:

  1. 对于一个发出的通知,多个对象能够做出反应,即1对多的方式实现简单
  2. controller能够传递context对象(dictionary),context对象携带了关于发送通知的自定义的信息
  3. 在调试的时候应用的工作以及控制过程难跟踪;

4.KVO

KVO是一个对象能够观察另外一个对象的属性的值,并且能够发现值的变化。

KVO:

  1. 能够提供一种简单的方法实现两个对象间的同步。例如:model和view之间同步;
  2. 能够对非我们创建的对象,即内部对象的状态改变作出响应,而且不需要改变内部对象(SKD对象)的实现;

5. 如何选择delegate、notification、KVO?

三种模式都是一个对象传递事件给另外一个对象,并且不要他们有耦合。

  1. delegate. 一对一
  2. notification 一对多,多对多
  3. KVO 一对一

三者各有自己的特点:

  • delegate 语法简洁,方便阅读,易于调试
  • notification 灵活多变,可以跨越多个类之间进行使用
  • KVO 实现属性监听,实现model和view同步
  • 可以根据实际开发遇到的场景来使用不同的方式

6. 若你去设计一个通知中心,你会怎样设计?

个人理解: 参考现有的通知中心

  1. 创建通知中心单例类,并在里面有个一个保存通知的全局NSDictionary
  2. 对于注册通知的类,将其注册通知名作为key, 执行的方法和类,以及一些参数做为一个数组为值
  3. 发送通知可以调用通知中心,通过字典key(通知名),找到对应的 类和方法进行执行调用传值.

7. Notification 和KVO区别

  • KVO提供一种机制,当指定的被观察的对像的属性被修改后,KVO会自动通知响应的观察者,KVC(键值编码)是KVO的基础
  • 通知:是一种广播机制,在实践发生的时候,通过通知中心对象,一个对象能够为所有关心这个时间发生的对象发送消息,两者都是观察者模式,不同在于KVO是被观察者直接发送消息给观察者,是对象间的直接交互,通知则是两者都和通知中心对象交互,对象之间不知道彼此
  • 本质区别,底层原理不一样.kvo 基于 runtime, 通知则是有个通知中心来进行通知

8.结构体与数组有什么区别?

  1. 结构体可以存不同类型的元素,而数组只能存同一类型
  2. 结构体类型需要我们自己定义.数组是用别的类型加元素个数
  3. 结构体内存分配方式很特别,使用对齐原则,不一定是所有元素的字节数和,而数组一定是所有元素的字节数和.
  4. 结构体指针可以指针名->结构体元素名(取元素);数组不行.

9. NSDictionary的实现原理是什么?

  • 哈希表(NSDictionary 是通过hash表来实现key和value之间的映射和存储的)

10.说一下静态库和动态库之间的区别

  • 静态库:以.a 和 .framework为文件后缀名。
  • 动态库:以.tbd(之前叫.dylib) 和 .framework 为文件后缀名。
  • 静态库:链接时会被完整的复制到可执行文件中,被多次使用就有多份拷贝。
  • 动态库:链接时不复制,程序运行时由系统动态加载到内存,系统只加载一次,多个程序共用(如系统的UIKit.framework等),节省内存。
  • // 静态库.a 和 framework区别.a 主要是二进制文件,不包含资源,需要自己添加头文件 .framework 可以包含头文件+资源信息

11.对于 oc 来讲,他的最大优缺点是什么? 如何缺点如何绕过这些不足

优点:

  1. OC是C语言的超集, 在C语言基础上增加了面向对象特性, 开发使用起来会方便高效.
  2. 分类可以快速扩展类的方法.扩展模块之间相互不影响
  3. 运行时特性,动态特性(动态类型,动态绑定,动态加载),提高了编程的灵活性
  4. OC可以与C / C++进行混编

缺点:

  1. 不支持多继承,多继承可以使用分类,协议,消息转发来弥补
  2. 不支持运算符重载
  3. 使用动态运行时类型,所有的方法都是函数调用,所以很多编译时优化方法都用不到,如内联函数等,性能低劣。
  4. 执行效率比C低,语法怪异

12. OC与 JS交互方式有哪些?

  1. 通过拦截URL
  2. 使用MessageHandler(WKWebView)
  3. JavaScriptCore (UIWebView)
  4. 使用三方库WebViewJavascriptBridge,可提供 js 调OC,以及OC掉JS

13. 通过JS调用OC代码(url拦截)一

  • 通过拦截url(适用于UIWebView和WKWebView)
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType {
    NSString *url = request.URL.absoluteString;
    if ([url rangeOfString:@"需要跳转源生界面的url判断"].location != NSNotFound) {
        return NO;
    }
    return YES;
}

14. JS调用OC代码(messageHander)二

  • 当JS端想传一些数据给iOS.那它们会调用下方方法来发送.
  • window.webkit.messageHandlers.<方法名>.postMessage(<数据>)上方代码在JS端写会报错,导致网页后面业务不执行.可使用try-catch执行.
  • 那么在OC中的处理方法如下.它是WKScriptMessageHandler的代理方法.name和上方JS中的方法名相对应.
- (void)addScriptMessageHandler:(id <WKScriptMessageHandler>)scriptMessageHandler name:(NSString *)name;

15. JS调用OC代码(WebViewJavascriptBridge)三

1. 设置 webViewBridge
_bridge = [WKWebViewJavascriptBridge bridgeForWebView:self.webView];
    [_bridge setWebViewDelegate:self];
2. 注册handler方法,需要和 前段协商好 方法名字,是供 JS调用Native 使用的。
    [_bridge registerHandler:@"scanClick" handler:^(id data, WVJBResponseCallback responseCallback) {
        // OC调用
        NSString *scanResult = @"http://www.baidu.com";
        // js 回调传参
        responseCallback(scanResult);
    }];
3. OC掉用JS
  [_bridge callHandler:@"testJSFunction" data:@"一个字符串" responseCallback:^(id responseData) {
        NSLog(@"调用完JS后的回调:%@",responseData);
    }];

16.OC调用JS代码

// 直接运行 使用 
NSString *jsStr = @"执行的JS代码";
[webView stringByEvaluatingJavaScriptFromString:jsStr];
​
// 使用JavaScriptCore框架
#import <JavaScriptCore/JavaScriptCore.h>  
- (void)webViewDidFinishLoad:(UIWebView *)webView {
    //获取webview中的JS内容
    JSContext *context = [webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];
    NSString *runJS = @"执行的JS代码";
    //准备执行的JS代码
    [context evaluateScript:runJS];
}

17. 遇到过BAD_ACCESS的错误吗?你是怎样调试的?

BAD_ACCESS 报错属于内存访问错误,会导致程序崩溃,错误的原因是访问了野指针(悬挂指针)。

  1. 设置全局断点快速定位问题代码所在行。
  2. 开启僵尸对象诊断
  3. Analyze分析
  4. 重写object的respondsToSelector方法,现实出现EXEC_BAD_ACCESS前访问的最后一个object。
  5. Xcode 7 已经集成了BAD_ACCESS捕获功能:Address Sanitizer。 用法如下:在配置中勾选✅Enable Address Sanitizer。

18.什么是函数式编程?链式

  • 函数式编程是一种编程模型,他将计算机运算看做是数学中函数的计算,并且避免了状态以及变量的概念。函数式编程就像流水线一样,一顺顺的把问题解决完,从一个起点开始,一个个的调用函数,因为上一个函数有返回值是工具类本身,所以一个函数执行完之后,可以用上一个函数继续调用,有点链式思维在里面。
  • Masonry 就是我们最常见的函数式编程,通过对象.方法1().方法2.....
[view mas_makeConstraints:^(MASConstraintMaker *make){     
make.top.bottom.left.right.equalTo(self.view);
}];

链式编程?

  • top.bottom.left.right.equalTo(self.view)通过"."语法,将需要执行的代码连续的书写,就叫做链式编程,它使得代码简单易懂。

19. 响应式编程?

  • 响应式编程是一种面向数据流和变化传播的编程范式。
  • 例如,在命令式编程环境中,a:=b+c表示将表达式的结果赋给a,而之后改变b或c的值不会影响a。但在响应式编程中,a的值会随着b或c的更新而更新。
  • Reactive Cocoa就是一个响应式编程的经典作品!

20.Block和Protocol的区别,Block是为了解决什么问题而使用的。

  • “代理和block的共同特性是回调机制,不同的是,代理的方法比较多,比较分散,公共接口,方法较多也选择用delegate进行解耦
  • 使用block的代码比较集中统一,异步和简单的回调用block更好”

Block是为了解决什么问题而使用的? 个人认为:

  • block为了多线程之间调度产生的;
  • block 也是一个OC对象,可以当参数传递,使用方便简单,灵活,很少的代码就可以实现代码回调.比协议省很多代码

21.说一下ios代码签名

  • 确保从app store下载的app是没被恶意篡改,如果修改则无法安装, 以及验证app开发者身份;

22.什么是app thinning(app 瘦身)

App Thinning可以译成“应用瘦身”。指的是App store 和操作系统在安装iOS或者watchOS的 app 的时候通过一些列的优化,尽可能减少安装包的大小,使得 app 以最小的合适的大小被安装到你的设备上。而这个过程包括了三个过程:slicing, bitcode, and on-demand resources。

  1. slicing 可以打包对应的 app 资源文件
  2. Bitcode 苹果会对包含Bitcode的二进制app进行二次优化,而不需要提交一个新的app版本到app store中。
  3. On-Demand Resources 按需加载

23. 如果没有instruments,该如何检测memory leak, zombie object 之类的问题。

  • 查看MLeaksFinder源码分析,国内三方

24.字典的工作原理 ?从100w个数据中是怎么快速去取value?

  1. NSDictionary(字典)是使用 hash表来实现key和value之间的映射和存储的,hash函数设计的好坏影响着数据的查找访问效率。

    • (void)setObject:(id)anObject forKey:(id )aKey;
  2. Objective-C 中的字典 NSDictionary 底层其实是一个哈希表,实际上绝大多数语言中字典都通过哈希表实现