1.Runtime
Runtime 是 Objective-C 的运行时系统,是一套基于 C 语言的 API,用于在程序运行时实现类、对象和消息的动态创建、修改和调用。
常见的应用场景:
1.获取类的属性列表,如字典转模型,实现自动归档和解档等
2.动态创建类和对象,如KVO等
3.方法交换
4.关联对象,如分类添加属性
5.动态添加方法
6.消息转发机制
2.UIView和CALayer的区别
1.UIView是UIKit框架中的一个类,而CALayer是Core Animation框架中的一个类;
2.UIView是一个可视化的视图,可以处理用户交互、布局等操作,而CALayer是一个不可见的图层,处理视图内容的绘制和动画;
3.每个UIView都有一个关联的CALayer,负责视图的渲染和动画。
3.iOS中的Runloop是什么?
Runloop是事件处理循环的一种机制,其本质是do-while循环,有事件处理唤醒(从内核态切换到用户态),事件处理完成后又进入休眠状态。Runloop和线程是一对一的关系,主线程的Runloop是默认开启的,子线程需要手动开启;Runloop有5种Mode,常用的为三种,NSRunloopDefaultMode,UITrackingRunloopMode,NSRunloopCommonMode;6种状态:1.启动;2.退出;3.即将进入休眠;4.被唤醒;5.即将处理timer事件;6.即将处理sources事件。
4.怎么将上层OC代码还原成 C++代码
- clang -rewrite-objc xxx.m -o xxx.cpp
- xcrun -sdk iphoneos clang -arch arm64 -rewrite-objc xxx.m -o xxx.cpp
5.dSYM编译后的位置:
~/Library/Developer/Xcode/Archives
6.iOS中的单例有什么优缺点?
优点:
1.全局唯一访问点:确保整个应用只存在一个实例,避免重复创建和资源浪费。
2.数据共享:方便跨模块共享数据(如用户信息、全局配置)。
3.延迟初始化:首次访问时才创建实例,节省内存。
4.线程安全:通过 dispatch_once或静态属性保证线程安全。
5.简化资源管理:统一管理文件、网络等共享资源。
缺点:
1.全局状态:单例的全局可访问性可能导致代码的耦合性增加,使得代码难以测试和维护。
2.内存常驻:生命周期与 App 相同,可能导致内存占用过高。
3.多线程问题:如果单例的初始化不是线程安全的,可能会在多个线程同时尝试初始化时导致问题。
4.扩展困难:单例模式使得扩展功能变得困难,因为单例类通常只有一个实例,而且其行为是全局的。
5.违反单一职责:易变成“上帝对象”,承担过多职责。
`在.h文件中声明单例方法:
@interface MySingleton : NSObject
+ (instancetype)sharedInstance;
@end
在.m文件中实现:
@implementation MySingleton
+ (instancetype)sharedInstance {
static MySingleton *sharedInstance = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sharedInstance = [[self alloc] init];
});
return sharedInstance;
}
// 为了防止通过其他方式创建实例,可以重写init方法,确保只能通过sharedInstance获取实例。
- (instancetype)init {
self = [super init];
if (self) {
// 初始化代码
}
return self;
}
// 如果需要,也可以重写allocWithZone:方法,防止通过alloc创建实例。
+ (instancetype)allocWithZone:(struct _NSZone *)zone {
return [self sharedInstance];
}
// 为了防止通过copy创建新实例,实现copyWithZone:方法(如果遵循NSCopying协议)
- (id)copyWithZone:(NSZone *)zone {
return self;
}
@end
class MySingleton {
// 静态常量,在第一次访问时初始化,并且保证线程安全
static let shared = MySingleton()
// 私有化初始化方法,防止外部创建实例
private init() {
// 初始化代码
}
// 如果需要,可以添加其他方法和属性
}
7.进程和线程的区别?
进程是一个正在运行的程序实例,拥有独立的内存空间和系统资源,每个应用都是一个独立的进程。 进程是资源分配的基本单位,每个进程都有自己独立的地址空间.
线程:进程内的一个执行单元,一个进程可以包含多个线程,这些线程共享进程的内存和资源。线程是CPU调度的基本单位.
8.野指针就是指向一个被释放或者被收回的对象,但是对指向该对象的指针没有做任何修改,以至于该指针让指向已经回收后的内存地址。
9.+load和+initialize方法的区别?
+load方法
1.+load方法是在类或分类被加载到运行时(Runtime)时调用,调用时机很早,在程序运行时在main函数之前调用。
2.+load方法的调用顺弃:类>分类,父类>子类,分类按Build Phases的顺序执行
3.调用方式:通过函数指针由系统调用,不同于objc_msgSend发送消息。
4.用途:方法交换,全局注册。
+initialize方法
1.+initialize方法是首次接受到消息时调用。
2.+initialize方法的调用顺序:分类>类,父类>子类 (如果子类没有实现则会调用父类,父类可能被调用多次),分类按Build Phases的逆序执行。
3.调用方式:+initialize方法是通过objc_msgSend发送消息调用的,因此遵循普通的继承规则。
4.在+initialize方法中可以安全的调用其他类,因为所有的类已加载完成,多用于类的初始化设置。