美文网首页
iOS面试题-OC

iOS面试题-OC

作者: CyrusCao | 来源:发表于2017-03-21 09:23 被阅读24次

1. 如何手动触发一个value的KVO


NSObject 有 willChangeValueForKey:didChangevlueForKey: 两个方法,会在 KVO 的时候调用,我们可以手动重写这两个方法。

2. @protocol 和 category 中使用 @property


  • 在协议中添加属性,只会生成accessor,并没有后为遵循协议的对象添加属性。
  • 分类中也是这样
  • 如果真的需要添加属性,可以用 runtime 方法:objc_setAssociatedObjectobjc_getAssociatedObject

3. Runtime


在类中向使用 runtime ,需要先导入<objc/message.h>。

消息机制

objc_msgSend(objc_getClass(“Person”), sel_registerName(“doSth”));

// 或者第一个参数是一个对象:
objc_msgSend(obj, sel_registerName(“doSth”));

// 也可以调用带参数的方法:
objc_msgSend(obj, sel_registerName(@selector(eat:),”food”));

// 注意这里参数和方法名之间是逗号关系

交换方法(method swizzing)

我们在类的 load 方法中进行方法的交换:

+ (void)load
{
  // 获得两个将要交换的方法
  Method oldMethod = class_getClassMethod(self, @selector(oldMethod:));
  Method newMethod = class_getClassMethod(self, @selector(newMethod:));
  // 交换:
  method_exchangeImplamentations(oldMethod, newMethod);
}

动态添加方法

会员机制、收费机制、部分受限制功能,这些都需要动态添加方法来实现。

只要对象调用了一个未实现的方法,就会调用 resolveInstanceMethod: 方法,所以我们可以在这个方法中进行添加:

class_addMethod(类,sel,方法名,类型);

动态添加属性

扩展属性只会生成 accessor 方法,不能在类中访问添加的成员变量,所以我们可以使用 runtime 添加属性:

objc_setAssociatedObject(对象, 属性名称, 属性值, 枚举策略);

访问这个动态添加的属性:

objc_getAssociatedObject(对象, 属性名);

为类添加属性的过程,实际上就是把属性和类关联起来,达到同生共死的目的。

消息转发

_objc_msgForward

4. 方法调用流程


  • 通过 isa 指针找到类对象或元类的方法列表
  • 注册方法编号
  • 根据方法编号找到对相应的方法的地址(SEL)
  • 在代码段中找到方法的具体实现(IMP)

5. 引用和指针的区别


  • 引用是指针的一种别称
  • 引用不能为空,指针可以
  • 引用初始化后不可改变,指针可以

6. 标准宏


#define Min(a,b) (((a)>=(b))?(b):(a))

由于是原样替换,所以要加上括号

7. 自定义对象实现copy


  • 使自定义对象遵循 NSCopy 协议
  • 重写父类的 copyWithZone 方法
    • 创建一个新对象
    • 设置当前对象的值给新对象
    • 返回新的对象
- (id) copyWithZone:(NSZone *)zone
{
  Person *p = [[[self class] allocWithZone] init];
  p.age = _age;
  p.name= _name;
  return p;
}

8. @class 和 #import 以及 @import


  • import 确保该头文件只被导入一次,无论在该文件中出现几次。
  • @class 告诉编译器,无需知道类的具体实现,只需要知道是个类就好了。这样可以避免类之间的依赖关系导致的重复编译。
    OC 中的对象都是动态分配内存,所以在编译时,编译器不需要了解这个对象的具体的内容,只需要获取指向这个对象的指针就可以了。这也回答了为什么 @class 关键字只会出现在 @interface 而不能出现在 @implementation 中。
  • @import 可以让你只引用一个库里的某一个类。

9. +load 和 +initialize 的区别是什么?


  • load 只要类所在文件被引用就会被调用
  • initialize 是在类或者其子类的第一个方法被调用前调用

所以如果类没有被引用进项目,就不会有load调用;但即使类文件被引用进来,但是没有使用,那么 initialize 也不会被调用。

10. 各种修饰符的特点以及使用场合


  • retainstrongretain 是 MRC 下的 strong
  • assignweakassign 是MRC下的 weakweak 必须作用于 oc 对象,而 assign 不必。weak 在作用对象销毁后直接将指针置为 nil。而 assign 会让属性的 setter 方法直接传递值,不考虑内存管理,所以通常用于基本数据类型。
  • `copy:对不可变对象使用时,可以防止外界的对实例变量的误改。

11. new、alloc/init 的区别


new 相当于一种快捷省事版的 alloc/init,其本质都是开辟内存空间并且初始化对象。但 alloc/init 在内部会使用一个 zone 机制,将相关的对象分配在相邻的内存中,以便检索对象时减少损耗。并且 new 无法在创建对象时给定参数。

12. 深复制与浅复制


  • [immutableObject copy] 浅复制
  • [immutableObject mutableCopy] 深复制
  • [mutableObject copy] 深复制
  • [mutableObject mutableCopy] 深复制

13. runtime 中,SEL 和 IMP 的区别


SEL只是方法编号,IMP(implementation) 是方法具体的地址。

14. 为什么 Extension 可以增加实例变量, 而 Category 不可以?


  • Extension: 在编译期进行,与类同生共死。
  • Category: 在运行期进行。

Category 在运行期间进行,但类在内存中的布局已经成型,添加实例变量会危险的修改类的结构。

15. __block__weak修饰符的区别


  • __block不管是ARC还是MRC模式下都可以使用,可以修饰对象,还可以修饰基本数据类型。
  • __weak只能在ARC模式下使用,也只能修饰对象,不能修饰基本数据类型(int)。
  • __block对象可以在block中被重新赋值,而__weak不可以。

16. isMemberOfClass 和 isKindOfClass 的异同


两者都能检测一个对象是否是某个类的成员,但后者还可以检测一个对象是否为某个类的后代,而前者却不行。

17. 谈谈instancetype和id的异同


  • 相同点
    都可以作为方法的返回类型

  • 不同点
    ①instancetype可以返回和方法所在类相同类型的对象,id只能返回未知类型的对象;
    ②instancetype只能作为返回值,不能像id那样作为参数

18. atomic和nonatomic的区别,默认是哪个?


  • atomic 是默认的,原子属性,防止多线程下的不安全
  • nonatomic 是可以添加的,如果是不用考虑多线程安全的话,可以用这个属性防止编译器生成过多的代码。

19. 向一个nil对象发送消息将会发生什么?


什么都不会发生。

objc是动态语言,每个方法在运行时会被动态转为消息发送,即:objc_msgSend(receiver, selector)。

20. 如何访问并修改一个类的私有属性?


  • 通过 KVC 可以访问一个类的私有属性
  • 通过 runtime 可以修改

21. accessibility 访问限制修饰符


  • @private:当前类
  • @protected:当前类以及子类
  • @package:不同包时是 private,同包使用时是public
  • @public:当前类以及其他类

22. 如何序列化自定义对象?


实现 NSCoding 协议。

23. 如何调试BAD_ACCESS错误?


Xcode 7 已经集成了BAD_ACCESS捕获功能:Address Sanitizer

24. 数据持久化方式以及使用场景


  • plist 文件 键值对存储,有嵌套关系。比如城市名称
  • preference(UserDefaults)轻量数据。比如偏好设置
  • SQLite 重量数据。比如视频
  • CoreData sqlite的封装。
  • NSKeyedAchiver 序列化自定义对象

25. 应用程序沙盒的目录结构


沙盒机制使应用之间不能互相访问数据

屏幕快照 2017-01-29 下午4.51.52.png

Documents

将应用程序的数据文件保存在该目录下.不过这些数据类型仅限于不可以再生的数据,可再生的数据文件应该存在LIbrary/Cache下

Library 它有两个子文件

  • caches 主要是缓存文件,用户使用过程中缓存都可以保存在这些目录中.保存那些可再生的文件,比如网络数据请求.因此,应用程序通常还需要负责删除这些文件.
  • Preferences 应用程序的偏好设置文件. 我们使用NSUserDefaults写的设置数据都会保存到该目录下的一个plist文件中 它会被iTunes同步

tmp

各种临时文件, 保存应用再次启动时不需要的文件.而且,当应用不在需要这些文件时应主动将其删除,因为该目录下的东西随时有可能被系统清除,目前已知的一种可能清理的原因是系统磁盘存储空间不足的时候

相关文章

  • ios面试题收集

    基础部分: iOS_Alex 1.最全的iOS面试题及答案2. OC问题3.2017年5月iOS招人心得 附面试题...

  • 2020年iOS最新面试题总结

    基础部分:1.iOS_Alex2.最全的iOS面试题及答案3. OC问题4.2017年5月iOS招人心得 附面试题...

  • iOS底层原理总结 - Class的本质↑

    通过对面试题的分析探索问题的本质内容 iOS底层原理总结 - OC对象的分类↑iOS底层原理总结 - OC对象的本...

  • OC面试题目合集

    这里用来记录一些OC面试题目(不定期更新, 会逐渐补充...) 视图面试题 IOS面试题(UIView) ----...

  • iOS188个面试题

    iOS面试题合集: 188个面试题 目录展示: 1、swift和oc的区别 2、编译链接 3、synthesize...

  • 探寻OC对象的本质

    iOS底层原理总结 - 探寻OC对象的本质 面试题:一个NSObject对象占用多少内存? 探寻OC对象的本质,我...

  • iOS-面试题-OC基础篇 (3) - (1)

    前言:面试笔试都是必考语法知识点。请认真复习和深入研究OC。 目录:iOS-面试题-OC基础篇 (1) - (84...

  • iOS-面试题-OC基础篇 (2) - (83)

    前言:面试笔试都是必考语法知识点。请认真复习和深入研究OC。 目录:iOS-面试题-OC基础篇 (1) - (84...

  • iOS底层原理总结 - 探寻OC对象的本质

    iOS底层原理总结 - 探寻OC对象的本质 原文链接 对小码哥底层班视频学习的总结与记录。面试题部分,通过对面试题...

  • iOS底层原理总结 - 探寻OC对象的本质

    iOS底层原理总结 - 探寻OC对象的本质 对小码哥底层班视频学习的总结与记录。面试题部分,通过对面试题的分析探索...

网友评论

      本文标题:iOS面试题-OC

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