iOS 面试题-2019.上

本文深入探讨了iOS开发中的内存管理,包括ARC下的内存规则、自动释放池原理,以及对象的生命周期。此外,还讲解了Objective-C的消息传递机制,包括方法调用流程、消息转发和内省机制。同时,涉及了离屏渲染及其性能影响,以及视图布局的相关方法。最后,文章讨论了线程安全和内存安全问题,提供了避免内存泄漏的实践建议。
摘要由CSDN通过智能技术生成
  1. UIViewCALayer是什么关系
  • UIView继承自UIResponder类,可以响应事件
  • CALayer直接继承自NSObject类,不可以响应事件
  • UIViewCALayerdelegate(CALayerDelegate)
  • UIView主要处理事件,CALayer负责绘制
  • 每个UIView内部都有一个CALayer在背后提供内容的绘制和显示,并且UIView的尺寸样式都由内部的Layer所提供。两者都有树状层级结构,Layer内部有SubLayersView内部有SubViews,但是LayerView多了个AnchorPoint
  1. NSCacheNSMutableDictionary的相同点与区别

相同点:
NSCacheNSMutableDictionary功能用法基本是相同的
区别:
NSCache是线程安全的,NSMutableDictionary线程不安全,Mutable开发的类一般都是线程不安全的
当内存不足时NSCache会自动释放内存(所以从缓存中取数据的时候总要判断是否为空)
NSCache可以指定缓存的限额,当缓存超出限额自动释放内存
NSCacheKey只是对对象进行了Strong引用,而非拷贝,所以不需要实现NSCopying协议

  1. atomic的实现机制;为什么不能保证绝对的线程安全(最好可以结合场景来说)
  • atomic会对属性的setter/getter方法进行加锁,这仅仅只能保证在操作setter/getter方法是安全的。不能保证其他线程的安全
  • 例如:线程1调用了某一属性的setter方法并进行到了一半,线程2调用其getter方法,那么会执行完setter操作后,再执行getter操作,线程2会获取到线程1setter后的完整的值;当几个线程同时调用同一属性的setter、getter方法时,会获取到一个完整的值,但获取到的值不可控
  1. iOS 中内省的几个方法

对象在运行时获取其类型的能力称为内省。内省可以有多种方法实现
OC运行时内省的4个方法:

  • 判断对象类型:
-(BOOL) isKindOfClass:            // 判断是否是这个类或者这个类的子类的实例
-(BOOL) isMemberOfClass:      // 判断是否是这个类的实例
  • 判断对象/类是否有这个方法
-(BOOL) respondsToSelector:                      // 判断实例是否有这样方法
+(BOOL) instancesRespondToSelector:      // 判断类是否有这个方法
  1. objc在向一个对象发送消息时,发生了什么

根据对象的isa指针找到该对象所属的类,去objc的对应的类中找方法
1.首先,在相应操作的对象中的缓存方法列表中找调用的方法,如果找到,转向相应实现并执行
2.如果没找到,在相应操作的对象中的方法列表中找调用的方法,如果找到,转向相应实现执行
3.如果没找到,去父类指针所指向的对象中执行1,2.
4.以此类推,如果一直到根类还没找到,转向拦截调用,走消息转发机制
5.如果没有重写拦截调用的方法,程序报错

  1. 你是否接触过OC中的反射机制?简单聊一下概念和使用
  • class反射
  • 通过类名的字符串形式实例化对象
Class class = NSClassFromString(@"student"); 
Student *stu = [[class alloc] init];
  • 将类名变为字符串
Class class = [Student class];
NSString *className = NSStringFromClass(class);
  • SEL的反射
  • 通过方法的字符串形式实例化方法
SEL selector = NSSelectorFromString(@"setName");
[stu performSelector:selector withObject:@"Mike"];
  • 将方法变成字符串
    NSStringFromSelector(@selector(setName:));
  1. 这个写法会出什么问题@property (nonatomic, copy) NSMutableArray *arr;

添加,删除,修改数组内元素的时候,程序会因为找不到对应的方法而崩溃。原因:是因为copy就是复制一个不可变NSArray的对象,不能对NSArray对象进行添加/修改

  1. 如何让自己的类用copy修饰符

若想令自己所写的对象具有拷贝功能,则需实现NSCopying协议。如果自定义的对象分为可变版本与不可变版本,那么就要同时实现NSCopyingNSMutableCopying协议。
具体步骤:
1.需声明该类遵从NSCopying协议
2.实现NSCopying协议的方法,具体区别戳这里

  • NSCopying协议方法为:
- (id)copyWithZone:(NSZone *)zone {
  MyObject *copy = [[[self class] allocWithZone: zone] init];
  copy.username = self.username;
  return copy;
}
  1. 为什么assign不能用于修饰对象

首先我们需要明确,对象的内存一般被分配到堆上,基本数据类型和oc数据类型的内存一般被分配在栈上
如果用assign修饰对象,当对象被释放后,指针的地址还是存在的,也就是说指针并没有被置为nil,从而造成了野指针。因为对象是分配在堆上的,堆上的内存由程序员分配释放。而因为指针没有被置为nil,如果后续的内存分配中,刚好分配到了这块内存,就会造成崩溃
assign修饰基本数据类型或oc数据类型,因为基本数据类型是分配在栈上的,由系统分配和释放,所以不会造成野指针

  1. 请写出以下代码输出

                
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值