乐趣区

关于iOS开发:iOS面试题基础

分类、扩大、代理、告诉、KVC、KVO、属性关键字

一、分类(Category)

*1、分类的作用?

申明公有办法,合成体积大的类文件

*2、分类的特点?

能够为零碎类增加分类。在运行时期间,将 Category 中的实例办法列表、协定列表、属性列表增加到主类中后(所有 Category 中的办法在办法列表中的地位是在主类的同名办法之前的),而后会递归调用所有类的 load 办法,这一切都是在 main 函数之前执行的。

*3、分类能够增加哪些内容?

实例办法,类办法,属性(增加 getter 和 setter 办法,并没有实例变量,增加实例变量须要用关联对象)

*4、如果工程里有两个分类 A 和 B,两个分类中有一个同名的办法,哪个办法最终失效?

取决于分类的编译程序,最初编译的那个分类的同名办法最终失效,而之前的都会被笼罩掉(这里并不是真正的笼罩,因为其余办法依然存在,只是拜访不到,因为在动静增加类的办法的时候是倒序遍历办法列表的,而最初编译的分类的办法会放在办法列表后面,拜访的时候就会先被拜访到,同理如果申明了一个和原类办法同名的办法,也会笼罩掉原类的办法)。

5、如果申明了两个同名的分类会怎么?

会报错,所以第三方的分类,个别都带有命名前缀

6、分类能增加成员变量吗?

不能。只能通过关联对象 (objc_setAssociatedObject) 来模仿实现成员变量,但其实质是关联内容,所有对象的关联内容都放在同一个全局容器哈希表中:AssociationsHashMap, 由 AssociationsManager 对立治理。

二、扩大(Extension)

1、扩大的作用?

申明公有属性,申明公有成员变量

2、扩大的特点?

编译时决定,只能以申明的模式存在,少数状况下放在在宿主类的.m 中,不能为零碎类增加扩大

三、代理(Delegate)

代理是一种设计模式,委托方申明协定,定义须要实现的接口,代理方依照协定实现办法

个别用 weak 来防止循环援用

四、告诉(NSNotification)

应用观察者模式用于实现跨层传递信息的机制。传递形式是一对多。

五、KVO(key-value-observing)

KVO 是观察者的另一实现

应用了 isa 混写(isa-swizzling)来实现 KVO

应用 setter 办法扭转值 KVO 会失效,应用 KVC 扭转值 KVO 也会失效,因为 KVC 会调用 setter 办法

- (void)setValue:(id)value {[self willChangeValueForKey:@"key"];
    [super setValue:value];
    [self didChangeValueForKey:@"key"];
}

间接赋值成员变量不会触发 KVO,因为不会调用 setter 办法,须要加上 willChangeValueForKey 和 didChangeValueForKey

六、KVC(key-value-coding)

KVC 能够通过 key 间接拜访对象的属性,或者给对象的属性赋值,这样能够在运行时动静的拜访或批改对象的属性

当调用 setValue:属性值 forKey:@”name“的代码时,,底层的执行机制如下:

1、程序优先调用 set<Key>: 属性值办法,代码通过 setter 办法实现设置。留神,这里的 <key> 是指成员变量名,首字母大小写要合乎 KVC 的命名规定,下同

2、如果没有找到 setName:办法,KVC 机制会查看 + (BOOL)accessInstanceVariablesDirectly 办法有没有返回 YES,默认该办法会返回 YES,如果你重写了该办法让其返回 NO 的话,那么在这一步 KVC 会执行 setValue:forUndefinedKey:办法,不过个别开发者不会这么做。所以 KVC 机制会搜寻该类外面有没有名为 <key> 的成员变量,无论该变量是在类接口处定义,还是在类实现处定义,也无论用了什么样的拜访修饰符,只在存在以 <key> 命名的变量,KVC 都能够对该成员变量赋值。

3、如果该类即没有 set<key>:办法,也没有_<key> 成员变量,KVC 机制会搜寻_is<Key> 的成员变量。

4、和下面一样,如果该类即没有 set<Key>:办法,也没有_<key> 和_is<Key> 成员变量,KVC 机制再会持续搜寻 <key> 和 is<Key> 的成员变量。再给它们赋值。

5、如果下面列出的办法或者成员变量都不存在,零碎将会执行该对象的 setValue:forUndefinedKey:办法,默认是抛出异样。

如果想禁用 KVC,重写 + (BOOL)accessInstanceVariablesDirectly 办法让其返回 NO 即可,这样的话如果 KVC 没有找到 set<Key>: 属性名时,会间接用 setValue:forUndefinedKey:办法。

当调用 valueForKey:@”name“的代码时,KVC 对 key 的搜寻形式不同于 setValue:属性值 forKey:@”name“,其搜寻形式如下:

1、首先按 get<Key>,<key>,is<Key> 的程序办法查找 getter 办法,找到的话会间接调用。如果是 BOOL 或者 Int 等值类型,会将其包装成一个 NSNumber 对象

2、如果下面的 getter 没有找到,KVC 则会查找 countOf<Key>,objectIn<Key>AtIndex 或 <Key>AtIndexes 格局的办法。如果 countOf<Key> 办法和另外两个办法中的一个被找到,那么就会返回一个能够响应 NSArray 所有办法的代理汇合(它是 NSKeyValueArray,是 NSArray 的子类),调用这个代理汇合的办法,或者说给这个代理汇合发送属于 NSArray 的办法,就会以 countOf<Key>,objectIn<Key>AtIndex 或 <Key>AtIndexes 这几个办法组合的模式调用。还有一个可选的 get<Key>:range: 办法。所以你想从新定义 KVC 的一些性能,你能够增加这些办法,须要留神的是你的办法名要合乎 KVC 的规范命名办法,包含办法签名。

3、如果下面的办法没有找到,那么会同时查找 countOf<Key>,enumeratorOf<Key>,memberOf<Key> 格局的办法。如果这三个办法都找到,那么就返回一个能够响应 NSSet 所的办法的代理汇合,和下面一样,给这个代理汇合发 NSSet 的音讯,就会以 countOf<Key>,enumeratorOf<Key>,memberOf<Key> 组合的模式调用。

4、如果还没有找到,再查看类办法 + (BOOL)accessInstanceVariablesDirectly, 如果返回 YES(默认行为),那么和先前的设值一样,会按_<key>,_is<Key>,<key>,is<Key> 的顺序搜索成员变量名,这里不举荐这么做,因为这样间接拜访实例变量毁坏了封装性,使代码更软弱。如果重写了类办法 + (BOOL)accessInstanceVariablesDirectly 返回 NO 的话,那么会间接调用 valueForUndefinedKey: 办法,默认是抛出异样

七、属性关键字

1、读写权限:readonly,readwrite(默认)

2、原子性:(atomic),nonatimic。atomic 读写平安,但效率低,不是相对的平安,比方操作数组,减少或移除,这种状况能够应用互斥锁来保障线程平安

3、援用计数

retain/strong

assign 润饰根本数据类型

weak 不扭转润饰对象的援用计数,对象开释后,weak 指针主动置为空

copy 分深拷贝和浅拷贝

浅拷贝,对象指针的复制,指标对象指针和源对象指针指向同一块内存空间,援用计数减少

深拷贝,对象内容的复制,开拓一块新的内存空间

可变的对象的 copy 和 mutableCopy 都是深拷贝

不可变对象的 copy 是浅拷贝,mutable 是深拷贝

copy 办法返回的都是不可变对象

@property (nonatomic, copy) NSMutableArray * array; 这样应用会 crash,因为 copy 的对象是不可变的

NSString 应用 copy 润饰不必 strong 润饰,用 strong 润饰一个 name 属性,如果赋值的是一个可变对象,当可变对象的值产生扭转的时候,name 的值也会扭转,这不是咱们冀望的,是因为 name 应用 strong 润饰后,指向跟可变对象雷同的一块内存地址,如果应用 copy 的话,则是深拷贝,会开拓一块新的内存空间,因而可变对象值变动时,也不会影响 name 的值。

————————————————

文章接下来还会继续更新,你也能够私信我及时获取最新材料以及面试相干材料。如果你有什么意见和倡议欢送给我留言。

求喜爱 IOS 的小伙伴关注!喜爱的话给一个赞吧!谢谢!谢谢!谢谢!

原文链接:iOS 面试题根底_永不止步的博客 -CSDN 博客_ios 面试题

退出移动版