iOS面试题-OC

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

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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 200,667评论 5 472
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 84,361评论 2 377
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 147,700评论 0 333
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,027评论 1 272
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,988评论 5 361
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,230评论 1 277
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,705评论 3 393
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,366评论 0 255
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,496评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,405评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,453评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,126评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,725评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,803评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,015评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,514评论 2 346
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,111评论 2 341

推荐阅读更多精彩内容