课程笔记:第4章OC语言特性相关面试问题

分类
1、你用分类都做了哪些事情?
-声明私有方法(比如定义一个分类,只有头文件放到对应宿主.m里,满足私有方法的声明和使用,不暴露具体实现。)
-分解体积庞大的类文件
-把Framework的私有方法公开

2、特点
-运行时决议,指的是在运行时,通过runtime将分类里面的内容添加到宿主类里面,当我们在编写或者编好分类文件后,它并没有把写好的内容添加到宿主类上,这个时候宿主类还没有分类中的方法,而是在运行时通过runtime把分类中的方法添加至宿主类上,这是分类的最大特点,也是分类和扩展的最大区别。
-可以为系统类添加分类,而扩展是不能给系统类添加扩展的。

3、分类中都可以添加哪些内容?
-实例方法
-类方法
-协议
-属性(只声明了get和set方法,并没有实现get和set方法,也没有生成实例变量)

4、加载调用栈

image.png

-分类添加的方法可以“覆盖”原类方法(当然不是真的覆盖)
-两个分类,里面有一个同名方法,最后编译的分类里面的方法被调用。
-名字相同的分类会引起编译报错

扩展
1、问题:一般用扩展做什么?
-声明私有属性
-声明私有方法
-声明私有成员变量

2、扩展的特点:
-编译时决议(分类是运行时决议)�
-只以声明的形式存在,多数情况下存在于宿主类的.m文件中(分类有声明有实现)
-不能为系统类添加扩展(系统类可以添加分类)

代理:
是一种软件设计模式(代理模式),并且可以添加属性
iOS中以@protocol的形式体现
代理和通知的区别是:代理是一对一的传递方式,而通知是一对多的传递方式

image.png

delegate一般声明为weak以规避循环引用,这样的结果是:
代理方----strong>委托方 同时 委托方-----weak>代理方

通知:
通知是使用 观察者模式 来实现的用于跨层传递消息的机制

image.png

1、问:如何实现通知机制?


image.png

在通知中心,有一个Notification_Map字典,里面存储着以通知名称为key,观察者组成的数组作为value

KVO

1、什么是KVO?
-KVO是Key-value observing的缩写
-KVO是Objective-C对观察者设计模式的一种实现
-Apple使用了isa混写(isa-swizzling)来实现KVO

image.png

当观察对象的某个属性时(当调用了addobserverforkeypath:),系统在运行时动态创建一个子类(这样是为了重写这个类的setter方法),并且将对象的isa指针指向新创建的这个类,修改isa的指向就是isa指针混写的一个标志,即isa混写技术

isa混写技术:
指的就是将isa指针动态重新指向新的类

setter方法重写的方法具体实现:

image.png
image.png

2、问:通过kvc设置value,kvo能否生效?
可以,原因是因为KVC改变属性值,会进入属性值的setter方法,从而触发KVO

3、问:通过成员变量直接赋值value,kvo能否生效?
不可以,但是可以通过手动修改setter方法,触发KVO
或者添加[self willChangeValueForKey:@"name"]; [self didChangeValueForKey:@"name"]; 这句话就可以了

总结:
使用setter方法改变值,KVO会生效
使用setValue:forKey:改变值,KVO会生效
成员变量直接修改需手动添加某些代码,KVO才会生效

KVC

1、KVC是Key-value coding的缩写。
里面有两个重要的方法:

  • (id)valueForKey:(NSString *)key;
  • (void)setValue:(nullable id)value forKey:(NSString *)key;

2、问:KVC是否有违面向对象思想

KVC只要知道某个对象的私有变量名称key,可以在外部将其value进行修改,也就是有违面向对象思想的。

valueForKey:的系统实现流程:


image.png

valueForKey:说白了就是通过一个key找到对应的value
找value可以是通过getter方法找,也可以通过直接找对应的实例变量
也就是,一个是方法,一个是实例变量,两种方法
图中
Accessor Method is exist?
就是通过getter方法找,有的话直接调用

Instance Var is exist?
就是有没有对应的实例变量,有的话调用

3、:Accessor Method(访问器方法)如何找方法呢?
通过getKey、key(正好是getter方法)、isKey三个方法,如果有则YES

这三个都是方法

4、:+(BOOL)accessInstanceVariablesDirectly的作用?
系统给我们提供了一个方法:
+(BOOL)accessInstanceVariablesDirectly,默认是返回YES

在返回YES的基础上,才会调用Instance Var is exist,判断是否存在相应的实例变量或者相似的实例变量

如果我们重写该方法,使其返回NO,那么直接报没有找到对应的值处理;不再进行实例变量的判断。

5:Instance Var is exist?判断规则是什么?
通过查找是否存在:_key、_isKey、key、isKey四个实例变量,如果有则YES

这四个都是实例变量

6、问:如果valueForKey:没有找到对应的value,会怎样?
如果valueForKey:没有找到对应的value,会调用valueForUndefinedKey:
从而造成崩溃

YZPerson *person1 = [[YZPerson alloc] init];
NSLog(@"person1.age = %@", [person1 valueForKey:@"age"]);

7、setValue:forKey:的系统实现流程:

image.png

属性关键字

1、问:属性关键字可以分为哪几类?
读写权限:readonly、readwrite(默认)
原子性:atomic(默认)、nonatomic
引用计数
setter\getter

atomic可以保证获取和赋值是线程安全的
但是,并不能保证在使用过程中是线程安全的(例如对一个使用atomic修饰的数组进行添加和删除元素并不能保证是线程安全的,只是保证在获取数组的值和赋值时是保证线程安全的)

引用计数:
retain(非ARC)\strong(ARC中)
assign(既可以修饰基本数据类型,也可以修修饰对象类型)\unsafe_unretain(只有在MRC中使用频繁,在ARC中基本不使用)
weak
copy

2、问:assign和weak的区别有哪些?
assign特点
可以修饰基本数据类型,如int、BOOL等
可以修饰对象类型,但不改变其引用计数器
当使用assign修饰对象,在对象释放的时候,指针仍然反向原对象地址,会产生悬垂指针,如果继续访问原对象可能导致
出现内存泄露或者程序异常。

3、weak
不可以修饰基本数据类型
修饰对象类型,但不改变其引用计数器
当使用weak修饰对象,在对象释放的时候,会自动置为nil

weak和assign的区别:assign既可以修饰基本类型,也可以修饰对象类型,weak只能修饰对象类型,第二个是assign修饰对象,在对象释放的时候,指针仍然反向原对象地址,而weak在释放以后被置为nil的。共同点是都不改变引用计数。

4、copy

浅拷贝


image.png

浅拷贝并没有新建一块内存
浅拷贝对原来的对象引用计数+1

深拷贝会新建一块内存,与原来的内存里面内容一样
深拷贝对原来的对象引用计数不变

深拷贝和浅拷贝的区别是否开辟了新的内存空间,是事影响了引用计数
对可变对象copy变为不可变,并且为深拷贝
对可变对象mutablecopy变为可变,深拷贝
总结:
可变对象的copy和mutableCopy均为深拷贝
不可变对象的mutableCopy是深拷贝,copy为浅拷贝。
copy返回的均是不可变对象

image.png

如果赋值过来是NSMutableArray,copy后其实是NSArray,如果对其进行添加或者删除操作,会造成程序崩溃

5、


image.png

问:为何会做 _obj != obj 的判断?不做可以吗?
如果不做,则先进行[_obj release];也就是原来的对象可能已经被释放掉了。再进行[obj retain]操作,会造成程序异常。

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

推荐阅读更多精彩内容

  • 一、分类 1、你用分类都做了哪些事?(1)、声明私有方法(2)、分解体积庞大的类文件(3)、把Framework的...
    骑着毛驴走起来阅读 526评论 0 2
  • 一、分类 1.分类的作用?声明私有方法,分解体积大的类文件,把framework的私有方法公开 2.分类的特点运行...
    長茳阅读 284评论 0 4
  • 1. 分类 你用分类都做了哪些事? 声明私有方法 分解体积庞大的文件 把framework的私有方法公开 特点 运...
    TAsama阅读 361评论 0 0
  • 1. 分类-category 如何使用声明私有方法分解体积庞大的类文件把Framework的私有方法公开等 分类的...
    X勒个F阅读 134评论 0 0
  • Category(分类) 声明私有方法 分解体积庞大的类文件 把Framework的私有方法公开 特点 运行时决议...
    Glenn_h阅读 84评论 0 0