1.OC reactiveobject
// 取消按钮点击事件绑定
[[self.chooseCompanyHeadView.chooseCompanySearchView.searchView.cancelButton rac_signalForControlEvents:UIControlEventTouchUpInside]
subscribeNext:^(__kindof UIControl * _Nullable x) {
STRONGSELF();
[strongSelf.chooseCompanyViewModel.searchCommand execute:@"cancelButton"];
}];
1. rac_signalForControlEvents:UIControlEventTouchUpInside
给取消按钮绑定了“点击”事件的信号。当用户点击按钮时,会触发这个信号
2. subscribeNext
订阅信号,监听点击事件,一旦点击就执行块内代码
3. strongSelf.chooseCompanyViewModel.searchCommand execute:@"cancelButton"]
调用 ViewModel 中的 searchCommand,并传入参数 "cancelButton"。这相当于告诉 ViewModel “取消按钮被点击了”
// 取消按钮点击事件绑定
self.searchCommand = [[RACCommand alloc] initWithSignalBlock:^RACSignal * _Nonnull(id _Nullable input) {
return [RACSignal createSignal:^RACDisposable * _Nullable(id<RACSubscriber> _Nonnull subscriber) {
STRONGSELF();
if ([input isEqualToString:@"cancelButton"]) { // 取消按钮点击
[strongSelf cancelButtonClick];
} else if ([input isEqualToString:@"personButton"]) { // 个人按钮点击
[strongSelf personButtonClick];
} else if ([input isEqualToString:@"addButton"]) { // 添加按钮点击
[strongSelf addButtonClick];
}
[subscriber sendCompleted];
return nil;
}];
}];
1.RACCommand 是 ReactiveObjC 用于封装“动作”或“命令”的类,它的作用是执行某个操作,并且这个操作会返回一个信号,方便链式处理。
2.initWithSignalBlock:
初始化时传入一个 block,这个 block 会根据传入的参数 input 返回一个信号。
3.createSignal:
在这里,信号是自定义创建的,订阅者会执行相应的方法:
4.判断传入的 input 字符串是哪个按钮对应的标识,比如 "cancelButton"、"personButton"、"addButton"。
根据不同的按钮标识,调用对应的处理方法:
cancelButtonClick
personButtonClick
addButtonClick
5.sendCompleted
发送完成事件,通知订阅者当前信号完成。
6.return nil
表示没有需要释放的资源。
7.如果报错断点是直接进 ReactiveObjC内部,我们怎么排查?
信号发出错误时,会触发 error 回调,并传入一个 NSError 对象。
[signal subscribeNext:^(id x) {
// 正常收到信号的值
NSLog(@"Received value: %@", x);
} error:^(NSError *error) {
// 错误捕获
NSLog(@"Error occurred: %@", error);
NSLog(@"Error domain: %@", error.domain); // 错误的域
NSLog(@"Error code: %ld", (long)error.code); // 错误的代码
NSLog(@"Error description: %@", error.localizedDescription); // 错误的描述
} completed:^{
// 完成时
NSLog(@"Signal completed");
}];
2.在 AFNetworking 中,多个请求默认是 并行 执行的
多个请求是并行执行的,因为每个请求都会在不同的网络线程上执行,互不干扰
3.在 AFNetworking 中,多个请求默认是 并行 执行的
AFURLSessionManagerURL 会话管理 是单例,确保对每个网络会话的统一管理
AFNetworkReachabilityManager 通过单例模式创建,并监听设备的网络状态变化
AFNetworkReachabilityManager 通过单例模式创建,并监听设备的网络状态变化
AFSecurityPolicy 安全配置单例,保证每个请求都可以使用统一的安全策略
通过这些单例,AFNetworking 提供了一个高效且易于使用的网络框架,帮助开发者更轻松地管理网络请求与响应,确保网络通信的稳定性与安全性
4.SEL dynamicSelector = @selector(dynamicMethod); 是通过isa指针找到这个类吗
是的。这行代码中没有直接使用 isa 指针,但动态方法的添加和查找最终是通过 isa 指针来实现
4.网络请求和图形算法分别怎么处理,CPU 的作用
网络请求:I/O 密集型,通常需要异步处理,以避免阻塞主线程。
图形算法:CPU 密集型,依赖于大量的计算,通常使用多线程、GPU 或同步并行处理来加速。
异步处理:网络请求常常使用异步处理,而图形算法则更多依赖并行计算来加速处理。
CPU 的作用:CPU 主要负责处理计算任务,在图形算法中执行大量的浮点计算,而在网络请求中,它处理请求和响应的解析等任务。
4.死锁的四个必要条件
一、死锁产生条件(四个必要条件)
- 互斥条件:资源被独占,同一时间只能被一个线程占用 A和B同时访问C资源
- 请求与保持条件:线程已持有资源,同时请求其他资源 A持有了C 还想持有B
- 不剥夺条件:已经分配给线程的资源不能强制从线程手中夺走,资源只能在线程释放后才能被其他线程访问。
- 循环等待条件:线程间形成资源等待环 A等待B访问C B等待A访问C
二、常见死锁场景
● 同步调用主队列任务:dispatch_sync(dispatch_get_main_queue(), ...) 同步串行添加任务
● 嵌套锁(如先锁A再锁B,另一线程先锁B再锁A)
● 递归锁未正确释放
三、应对策略
- 避免嵌套锁:按统一顺序获取锁(如始终先锁A再锁B)
- 使用超时机制:NSLock的tryLock或lockBeforeDate:
- 破坏循环等待:资源编号,按顺序获取锁
- 检测工具:Instruments的Deadlocks模板检测死锁