iOS之面试笔记4(runLoop 内存管理机制)

news/2024/7/20 14:55:59 标签: 面试, 内存管理

这是去年下半年面试所遇到的问题,整理了下,供大家参考下。不对之处请指教!

1.runloop和线程有什么关系?

总的说来,Run loop,正如其名,loop表示某种循环,和run放在一起就表示一直在运行着的循环。实际上,run loop和线程是紧密相连的,可以这样说run loop是为了线程而生,没有线程,它就没有存在的必要。Run loops是线程的基础架构部分, Cocoa 和 CoreFundation 都提供了 run loop 对象方便配置和管理线程的 run loop (以下都以 Cocoa 为例)。每个线程,包括程序的主线程( main thread )都有与之相应的 run loop 对象。 runloop 和线程的关系: 主线程的run loop默认是启动的。 iOS的应用程序里面,程序启动后会有一个如下的main()函数

int main(int argc, char * argv[]) {
  @autoreleasepool {
      return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
  }
}
复制代码

重点是UIApplicationMain()函数,这个方法会为main thread设置一个NSRunLoop对象,这就解释了:为什么我们的应用可以在无人操作的时候休息,需要让它干活的时候又能立马响应。 对其它线程来说,run loop默认是没有启动的,如果你需要更多的线程交互则可以手动配置和启动,如果线程只是去执行一个长时间的已确定的任务则不需要。 在任何一个 Cocoa 程序的线程中,都可以通过以下代码来获取到当前线程的 run loop 。

NSRunLoop *runloop = [NSRunLoop currentRunLoop];
复制代码

2.runloop的mode作用是什么?

mode 主要是用来指定事件在运行循环中的优先级的,分为:

NSDefaultRunLoopMode(kCFRunLoopDefaultMode):默认,空闲状态
UITrackingRunLoopMode:ScrollView滑动时
UIInitializationRunLoopMode:启动时
NSRunLoopCommonModes(kCFRunLoopCommonModes):Mode集合
复制代码

苹果公开提供的 Mode 有两个:

NSDefaultRunLoopMode(kCFRunLoopDefaultMode)
NSRunLoopCommonModes(kCFRunLoopCommonModes)
复制代码

3.以+ scheduledTimerWithTimeInterval...的方式触发的timer,在滑动页面上的列表时,timer会暂定回调,为什么?如何解决?

RunLoop只能运行在一种mode下,如果要换mode,当前的loop也需要停下重启成新的。利用这个机制,ScrollView滚动过程中NSDefaultRunLoopMode(kCFRunLoopDefaultMode)的mode会切换到UITrackingRunLoopMode来保证ScrollView的流畅滑动:只能在NSDefaultRunLoopMode模式下处理的事件会影响ScrollView的滑动。 如果我们把一个NSTimer对象以NSDefaultRunLoopMode(kCFRunLoopDefaultMode)添加到主运行循环中的时候, ScrollView滚动过程中会因为mode的切换,而导致NSTimer将不再被调度。 同时因为mode还是可定制的,所以: Timer计时会被scrollView的滑动影响的问题可以通过将timer添加到NSRunLoopCommonModes(kCFRunLoopCommonModes)来解决。代码如下:

//将timer添加到NSDefaultRunLoopMode中
[NSTimer scheduledTimerWithTimeInterval:1.0
     target:self
     selector:@selector(timerTick:)
     userInfo:nil
     repeats:YES];
//然后再添加到NSRunLoopCommonModes里
NSTimer *timer = [NSTimer timerWithTimeInterval:1.0
     target:self
     selector:@selector(timerTick:)
     userInfo:nil
     repeats:YES];
[[NSRunLoop currentRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];
复制代码

4.objc使用什么机制管理对象内存?

通过 retainCount (引用计数器)的机制来决定对象是否需要释放。 每次 runloop 的时候,都会检查对象的 retainCount,如果retainCount 为 0,说明该对象没有地方需要继续使用了,可以释放掉了。

5.BAD_ACCESS在什么情况下出现?

访问了野指针,比如对一个已经释放的对象执行了release、访问已经释放对象的成员变量或者发消息。 死循环

6.苹果是如何实现autoreleasepool的?

autoreleasepool 以一个队列数组的形式实现,主要通过下列三个函数完成. objc_autoreleasepoolPush objc_autoreleasepoolPop objc_autorelease 看函数名就可以知道,对 autorelease 分别执行 push,和 pop 操作。销毁对象时执行release操作。 举例说明:我们都知道用类方法创建的对象都是 Autorelease 的,那么一旦 Person 出了作用域,当在 Person 的 dealloc 方法中打上断点,我们就可以看到这样的调用堆栈信息:

7.以下代码运行结果如何?

- (void)viewDidLoad {
    [super viewDidLoad];
    NSLog(@"1");
    dispatch_sync(dispatch_get_main_queue(), ^{
        NSLog(@"2");
    });
    NSLog(@"3");
}
复制代码

只输出:1 。发生主线程锁死(同步主队列造成的死锁问题)。

8.addObserver:forKeyPath:options:context:各个参数的作用分别是什么,observer中需要实现哪个方法才能获得KVO回调?

// 添加键值观察
/*
1 观察者,负责处理监听事件的对象
2 观察的属性
3 观察的选项
4 上下文
*/
[self.person addObserver:self forKeyPath:@"name" options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld context:@"Person Name"];
observer中需要实现一下方法:
复制代码
// 所有的 kvo 监听到事件,都会调用此方法
/*
 1. 观察的属性
 2. 观察的对象
 3. change 属性变化字典(新/旧)
 4. 上下文,与监听的时候传递的一致
 */
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context;
复制代码

9.KVC的keyPath中的集合运算符如何使用?

必须用在集合对象上或普通对象的集合属性上 简单集合运算符有@avg, @count , @max , @min ,@sum, 格式 @"@sum.age"或 @"集合属性.@max.age"


http://www.niftyadmin.cn/n/839048.html

相关文章

watch使用

watch深度监听: watch监听对象,同时用 deep:true 深度监听 监听对象值得变化必须用deep 遇到的问题:如果这个对象内部属性具有数组或者其他的对象,那么通过watch打印出的newValue和oldValue的结果是一样的,因为数据同…

计算机技术在医学领域的运用,计算机在医疗系统中的应用

丁 锐(南京市妇幼保健院,江苏 南京 210000)摘 要:随着信息化技术的发展,计算机技术在各个领域都有相当广泛的应用,计算机的应用可以提高信息沟通的效率,可以提高问题处理的能力。当前,计算机信息技术不断…

python函数的定义(含扩展)

python函数的定义 def func(arg1,arg2,arg3):函数体return arg4,arg5,arg6补充:如果想给某个参数一个默认值,不用每次都输入的话,可以采用以下方法(以参数arg2默认值设为233为例子) def func(arg1,arg2233,arg3):函数…

动态代理Proxy

对原有功能的增强; 静态代理限定了只能是一个类 动态代理可以根据传入的对象类型来生成对应类型的代理对象 动态代理实现 实现InvocationHandler,实现这个接口会重写一个方法,这个方法是代理类的增强方法 public class KeywordFilter implements InvocationHandle…

Oracle 数据库连接操作符(||)

在oracle中,字符串的连接用双竖线(||)表示,如下实例 1. select ename,job from emp where sal > 2000; 2. select ename||is a||job from emp where sal>2000; Oracle中字符串可以用单引号,也可以用双引号&…

惊!C++竟然还能有这种操作——高性能深度学习库(DLL)

更多深度文章,请关注云计算频道:https://yq.aliyun.com/cloud 作为一个深度学习的老司机,你是不是以为只有Python才能够玩转深度学习?如果是这样的话,那么本文作者可能就要教你怎么“做人”了。毕竟大牛的世界我们不懂…

计算机二级文字处理解题步骤,计算机二级Msoffice-文字处理答案(解题步骤).docx...

1、 在考生文件夹下打开文档 word.docx ,按照要求完成下列操作并以该文件名(word.docx) 保存文件。按照参考样式 "word 参考样式.gif" 完成设置和制作。具体要求如下:(1)设置页边距为上下左右各 2.7 厘米,装订线在左侧;…

[转]所有人都在渲染程序员的中年危机,我们却在劝你重新学会学习

https://news.cnblogs.com/n/585781/ ------------------------------------------------------------------------------------------------------------------------------------------------------ 阅读和理解是不够的,你还需要记住你学的内容。进行主动阅读——…