UIView
和CALayer
是什么关系
UIView
继承自UIResponder
类,可以响应事件CALayer
直接继承自NSObject
类,不可以响应事件UIView
是CALayer
的delegate
(CALayerDelegate
)UIView
主要处理事件,CALayer
负责绘制- 每个
UIView
内部都有一个CALayer
在背后提供内容的绘制和显示,并且UIView
的尺寸样式都由内部的Layer
所提供。两者都有树状层级结构,Layer
内部有SubLayers
,View
内部有SubViews
,但是Layer
比View
多了个AnchorPoint
NSCache
和NSMutableDictionary
的相同点与区别
相同点:
NSCache
和NSMutableDictionary
功能用法基本是相同的
区别:
NSCache
是线程安全的,NSMutableDictionary
线程不安全,Mutable开发的类
一般都是线程不安全的
当内存不足时NSCache
会自动释放内存(所以从缓存中取数据的时候总要判断是否为空)
NSCache
可以指定缓存的限额,当缓存超出限额自动释放内存
NSCache
的Key
只是对对象进行了Strong
引用,而非拷贝,所以不需要实现NSCopying
协议
atomic
的实现机制;为什么不能保证绝对的线程安全(最好可以结合场景来说)
atomic
会对属性的setter/getter
方法进行加锁,这仅仅只能保证在操作setter/getter
方法是安全的。不能保证其他线程的安全- 例如:线程1调用了某一属性的
setter
方法并进行到了一半,线程2调用其getter
方法,那么会执行完setter
操作后,再执行getter
操作,线程2会获取到线程1setter
后的完整的值;当几个线程同时调用同一属性的setter、getter
方法时,会获取到一个完整的值,但获取到的值不可控
- iOS 中内省的几个方法
对象在运行时获取其类型的能力称为内省。内省可以有多种方法实现
OC运行时内省的4个方法:
- 判断对象类型:
-(BOOL) isKindOfClass: // 判断是否是这个类或者这个类的子类的实例
-(BOOL) isMemberOfClass: // 判断是否是这个类的实例
- 判断对象/类是否有这个方法
-(BOOL) respondsToSelector: // 判断实例是否有这样方法
+(BOOL) instancesRespondToSelector: // 判断类是否有这个方法
objc
在向一个对象发送消息时,发生了什么
根据对象的isa指针找到该对象所属的类,去objc的对应的类中找方法
1.首先,在相应操作的对象中的缓存方法列表中找调用的方法,如果找到,转向相应实现并执行
2.如果没找到,在相应操作的对象中的方法列表中找调用的方法,如果找到,转向相应实现执行
3.如果没找到,去父类指针所指向的对象中执行1,2.
4.以此类推,如果一直到根类还没找到,转向拦截调用,走消息转发机制
5.如果没有重写拦截调用的方法,程序报错
- 你是否接触过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:));
- 这个写法会出什么问题
@property (nonatomic, copy) NSMutableArray *arr;
添加,删除,修改数组内元素的时候,程序会因为找不到对应的方法而崩溃。原因:是因为
copy
就是复制一个不可变NSArray
的对象,不能对NSArray
对象进行添加/修改
- 如何让自己的类用
copy
修饰符
若想令自己所写的对象具有拷贝功能,则需实现
NSCopying
协议。如果自定义的对象分为可变版本与不可变版本,那么就要同时实现NSCopying
与NSMutableCopying
协议。
具体步骤:
1.需声明该类遵从NSCopying
协议
2.实现NSCopying
协议的方法,具体区别戳这里
NSCopying
协议方法为:
- (id)copyWithZone:(NSZone *)zone {
MyObject *copy = [[[self class] allocWithZone: zone] init];
copy.username = self.username;
return copy;
}
- 为什么
assign
不能用于修饰对象
首先我们需要明确,对象的内存一般被分配到堆上,基本数据类型和oc数据类型的内存一般被分配在栈上
如果用assign
修饰对象,当对象被释放后,指针的地址还是存在的,也就是说指针并没有被置为nil
,从而造成了野指针。因为对象是分配在堆上的,堆上的内存由程序员分配释放。而因为指针没有被置为nil
,如果后续的内存分配中,刚好分配到了这块内存,就会造成崩溃
而assign
修饰基本数据类型或oc数据类型,因为基本数据类型是分配在栈上的,由系统分配和释放,所以不会造成野指针
- 请写出以下代码输出