zoukankan      html  css  js  c++  java
  • 面试题的总结(一)

    一.MRC 和ARC 内存管理?
    Objective-c中提供了两种内存管理机制MRC(MannulReference Counting)和ARC(Automatic Reference Counting),分别提供对内存的手动和自动管理,来满足不同的需求。其实arc 内部机制原理也是来源于mrc ,arc 是在 iOS 5/ Mac OS X 10.7 开始导入,利用 Xcode4.2 可以使用该机能。arc的首要目的就是让代码简洁化,编程简单化,开发更顺心应手,减少不必要的小问题小疏忽;顾名思义,自动引用计数管理,关于内存的申请,使用和释放过程都交给系统自动实现,我们可也不用关系里面的过程,但是事实上还是mrc的原理,只是是系统帮我们做了管理;
    mrc,手动引用计数器管理,是在我们申请到某一块内存,在使用之后,要手动释放,释放机理涉及到计数器问题,如果未释放内存,会造成内存的浪费,俗称内存泄露,甚至引起很多未知的错误结果,这对程序有威胁很大,但是,何时释放,怎么释放,注意哪些问题,很有讲究,这就是mrc的不便之处,也是苹果推出arc的缘由;
    mrc的具体机理,计数器是什么,在程序过程中的变化,在达到什么程度会释放内存,怎么操作;建议查阅相关文档;
    mrc ,在代码上下形式主要表现为,调用该对象时,要做retain操作,使用完成后要release,最后还要重写dealloc方法,对该类的所有对象做释放,所以在mrc的代码会有autorelease,retain,release等词语,
    而arc不允许有这些词汇,应为这些操作都由系统自动完成。

    引用计数器
    1.和内存管理相关的方法
    1)alloc 引用计数器自动设为1
    2)retain 引用计数器+1 返回了经过+1以后的当前实例对象
    3)release 引用计数器-1,并不一定是释放
    4)retainCount 获取引用计数器的值
    5)dealloc 当实例对象被销毁之前,系统自动调用。
    一定要调[super dealloc]

    和内存管理相关的名词
    1)僵尸对象:此对象被销毁,不能再使用,不能给它发送任何消息
    2)野指针:指向僵尸对象(不可用的内存)的指针,给野指针发送消息将会产生不可控的后果。
    3)空指针:没有指向任何对象的指针,给空指针发消息不会产生任何行为

    内存管理原则
    1.如果你想持有某个对象,就必须负责让做一次retain操作,引用计数器+1.
    2.如果你想放弃对某个对象的持有权,就要负责让其做一次release操作,引用计数器-1.

    3.谁retain,谁release。

    二.retain 和copy的区别?
    copy是创建一个新对象,retain是创建一个指针,引用对象计数加1。Copy属性表示两个对象内容相同,新的对象retain为1 ,与旧有对象的引用计数无关,旧有对象没有变化。copy减少对象对上下文的依赖。

      retain属性表示两个对象地址相同(建立一个指针,指针拷贝),内容当然相同,这个对象的retain值+1也就是说,retain 是指针拷贝,copy 是内容拷贝。

    三、CALayer 的用处?
    1.UIView是iOS系统中界面元素的基础,所有的界面元素都继承自它。它本身完全是由CoreAnimation来实现的(Mac下似乎不是这样)。它真正的绘图部分,是由一个叫CALayer(Core Animation Layer)的类来管理。UIView本身,更像是一个CALayer的管理器,访问它的跟绘图和跟坐标有关的属性,例如frame,bounds等等,实际上内部都是在访问它所包含的CALayer的相关属性。 2.UIView有个layer属性,可以返回它的主CALayer实例,UIView有一个layerClass方法,返回主layer所使用的类,UIView的子类,可以通过重载这个方法,来让UIView使用不同的CALayer来显示,例如通过 1 - (class) layerClass { 2 return ([CAEAGLLayer class]); 3 } 使某个UIView的子类使用GL来进行绘制。 3.UIView的CALayer类似UIView的子View树形结构,也可以向它的layer上添加子layer,来完成某些特殊的表示。例如下面的代码 1 grayCover = [[CALayer alloc] init]; 2 grayCover.backgroundColor = [[[UIColor blackColor] colorWithAlphaComponent:0.2] CGColor]; 3 [self.layer addSubLayer: grayCover]; 会在目标View上敷上一层黑色的透明薄膜。 4.UIView的layer树形在系统内部,被系统维护着三份copy(这段理解有点吃不准)。 第一份,逻辑树,就是代码里可以操纵的,例如更改layer的属性等等就在这一份。 第二份,动画树,这是一个中间层,系统正在这一层上更改属性,进行各种渲染操作。 第三份,显示树,这棵树的内容是当前正被显示在屏幕上的内容。 这三棵树的逻辑结构都是一样的,区别只有各自的属性。 5.动画的运作 UIView的主layer以外(我觉得是这样),对它的subLayer,也就是子layer的属性进行更改,系统将自动进行动画生成,动画持续时间有个缺省时间,个人感觉大概是0.5秒。在动画时间里,系统自动判定哪些属性更改了,自动对更改的属性进行动画插值,生成中间帧然后连续显示产生动画效果。 6.坐标系系统(对position和anchorPoint的关系还是犯晕) CALayer的坐标系系统和UIView有点不一样,它多了一个叫anchorPoint的属性,它使用CGPoint结构,但是值域是0~1,也就是按照比例来设置。这个点是各种图形变换的坐标原点,同时会更改layer的position的位置,它的缺省值是{0.5, 0.5},也就是在layer的中央。 某layer.anchorPoint = CGPointMake(0.f, 0.f); 如果这么设置,layer的左上角就会被挪到原来的中间的位置, 加上这样一句就好了 某layer.position = CGPointMake(0.f, 0.f);

    四、多线程?
    进程:

    正在进行中的程序被称为进程,负责程序运行的内存分配;

    每一个进程都有自己独立的虚拟内存空间.

    线程:(主线程最大占1M的栈区空间,每条子线程最大占512K的栈区空间)

    线程是进程中一个独立的执行路径(控制单元);

    一个进程中至少包含一条线程,即主线程;

    可以将耗时的执行路径(如网络请求)放在其他线程中执行;

    线程不能被杀掉,但是可以暂停/休眠一条线程.

    创建线程的目的:

    开启一条新的执行路径,运行指定的代码,与主线程中的代码实现同时运行.

    多任务调度系统:

    每个应用程序由操作系统分配的短暂的时间片(Timeslice)轮流使用CPU,由于CPU对每个时间片的处理速度非常快,因此,用户看来这些任务好像是同时执行的.

    并发:

    指两个或多个任务在同一时间间隔内发生,但是,在任意一个时间点上,CPU只会处理一个任务.

    多线程的优势:

    1> 充分发挥多核处理器优势,将不同线程任务分配给不同的处理器,真正进入"并行运算"状态;

    2> 将耗时的任务分配到其他线程执行,由主线程负责统一更新界面会使应用程序更加流畅,用户体验更好;

    3> 当硬件处理器的数量增加,程序会运行更快,而程序无需做任何调整.

    弊端:

    新建线程会消耗内存空间和CPU时间,线程太多会降低系统的运行性能.

    五、iOS多线程技术特点?
    1.NSThread:

    1> 使用NSThread对象建立一个线程非常方便;

    2> 但是!要使用NSThread管理多个线程非常困难,不推荐使用;

    3> 技巧!使用[NSThread currentThread]跟踪任务所在线程,适用于这三种技术.

    2.NSOperation/NSOperationQueue:

    1> 是使用GCD实现的一套Objective-C的API;

    2> 是面向对象的多线程技术;

    3> 提供了一些在GCD中不容易实现的特性,如:限制最大并发数量,操作之间的依赖关系.

    3.GCD---Grand Central Dispatch:

    1> 是基于C语言的底层API;

    2> 用Block定义任务,使用起来非常灵活便捷;

    3> 提供了更多的控制能力以及操作队列中所不能使用的底层函数.

    iOS的开发者需要了解三种多线程技术的基本使用,因为在实际开发中会根据实际情况选择不同的多线程技术.

    GCD基本思想

    GCD的基本思想就是将操作S放在队列S中去执行.

    1> 操作使用Blocks定义;

    2> 队列负责调度任务执行所在的线程以及具体的执行时间;

    3> 队列的特点是先进先出(FIFO)的,新添加至队列的操作都会排在队尾.

    提示:

    GCD的函数都是以dispatch(分派/调度)开头的.

    队列:

    dispatch_queue_t

    串行队列: 队列中的任务只会顺序执行;

    并行队列: 队列中的任务通常会并发执行.

    操作:

    dispatch_async 异步操作,会并发执行,无法确定任务的执行顺序;

    dispatch_sync 同步操作,会依次顺序执行,能够决定任务的执行顺序.

    队列不是线程,也不表示对应的CPU.队列就是负责调度的.多线程技术的目的,就是为了在一个CPU上实现快速切换!

    在串行队列中:

    同步操作不会新建线程,操作顺序执行(没用!);

    异步操作会新建线程,操作顺序执行(非常有用!) (应用场景:既不影响主线程,又需要顺序执行的操作).

    在并行队列中:

    同步操作不会新建线程,操作顺序执行;

    异步操作会新建多个线程,操作无序执行(有用,容易出错),队列前如果有其他任务,会等待前面的任务完成之后再执行.应用场景:既不影响主线程,又不需要顺序执行的操作.

    全局队列:

    全局队列是系统的,直接拿过来(GET)用就可以,与并行对立类似,但调试时,无法确认操作所在队列.

    主队列:

    每一个应用程序都对应唯一一个主队列,直接GET即可,在多线程开发中,使用主队列更新UI;

    注意:

    主队列中的操作都应该在主线程上顺序执行,不存在异步的概念.

    如果把主线程中的操作看作是一个大的Block,那么除非主线程被用户杀掉,否则永远不会结束.所以主队列中添加的同步操作永远不会被执行,会死锁.


    // 全局队列,都在主线程上执行,不会死锁
    dispatch_queue_t q = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    // 并行队列,都在主线程上执行,不会死锁
    dispatch_queue_t q = dispatch_queue_create("m.baidu.com", DISPATCH_QUEUE_CONCURRENT);
    // 串行队列,会死锁,但是会执行嵌套同步操作之前的代码
    dispatch_queue_t q = dispatch_queue_create("m.baidu.com", DISPATCH_QUEUE_SERIAL);
    // 直接死锁
    dispatch_queue_t q = dispatch_get_main_queue();
    同步操作dispatch_sync的应用场景:

    阻塞并行队列的执行,要求某一操作执行后再进行后续操作,如用户登录.

    确保块代码之外的局部变量确实被修改.

    [NSThread sleepForTimeInterval:2.0f] 通常在多线程调试中用于模拟耗时操作,在发布的应用程序中,不要使用此方法!

    无论什么队列和什么任务,线程的创建和回收都不需要程序员参与.线程的创建回收工作是由队列负责的.

    GCD优点:

    1> 通过GCD,开发者不用再直接跟线程打交道,只需要向队列中添加代码块即可.

    2> GCD在后端管理着一个线程池,GCD不仅决定着代码块将在哪个线程被执行,它还根据可用的系统资源对这些线程进行管理,从而让开发者从线程管理的工作中解放出来;通过集中的管理线程,缓解大量线程被创建的问题.

    3> 使用GCD,开发者可以将工作考虑为一个队列,而不是一堆线程,这种并行的抽象模型更容易掌握和使用.

    六、CoreAnimation?
    CAAnimation可分为四种:

    1.CABasicAnimation
    通过设定起始点,终点,时间,动画会沿着你这设定点进行移动。可以看做特殊的CAKeyFrameAnimation
    2.CAKeyframeAnimation
    Keyframe顾名思义就是关键点的frame,你可以通过设定CALayer的始点、中间关键点、终点的frame,时间,动画会沿你设定的轨迹进行移动
    3.CAAnimationGroup
    Group也就是组合的意思,就是把对这个Layer的所有动画都组合起来。PS:一个layer设定了很多动画,他们都会同时执行,如何按顺序执行我到时候再讲。
    4.CATransition
    这个就是苹果帮开发者封装好的一些动画


    补充:
    •Core Animation是非常强大的动画处理API,使用它能做出非常炫丽的动画效果,而且往往是事半功倍,使用它需要先添加QuartzCore.framework和引入对应的框架<QuartzCore/QuartzCore.h>
    •CALayer中很多属性都可以通过CAAnimation实现动画效果,包括:opacity、position、transform、bounds、contents等(可以在API文档中搜索:CALayer Animatable Properties)
    •通过调用CALayer的addAnimation:forKey增加动画到层(CALayer)中,这样就能触发动画了。通过调用removeAnimationForKey可以停止层中的动画
    •Core Animation的动画执行过程都是在后台操作的,不会阻塞主线程

    开发步骤
    ①初始化一个动画对象(CAAnimation)并设置一些动画相关属性
    ②添加动画对象到层(CALayer)中,开始执行动画
    ①CAAnimation

    七、sdwebimage

    实现加载网络图片,并可以设置图片加载前的默认图片,监听图片加载进度以及图片加载完成事件

    #import导入"UIImageView+WebCache.h",

    [_imageView setImageWithURL:url placeholderImage:nil options:SDWebImageRetryFailed progress:^(NSInteger receivedSize, NSInteger expectedSize) {//查看下载进度

    NSLog(@"receive = %d,expected = %d",receivedSize,expectedSize);

    } completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType) {//加载成功后调用

    NSLog(@"加载成功");

    }];

    调用此方法会下载URL所指向的网络图片(如果本地无缓存的话),并且可以监听下载进度以及下载完成事件

    #import导入“SDImageCache.h”可实现储存加载的图像到缓存,并且可以找出储存的缓存,使图片显示


    八、SizeClass 本质上就是AutoLayout

    AutoLayout到底是什么?其实就是个约束布局
    如果你用了AutoLayout 那么做动画的时候 你就不要再操作 Frame bounds center 等position属性

    因为这些动画都是临时的 下次的View 被 setNeedsUpdateConstraint 这些全都失效

    但是其他的可动画属性(Animation Properties) 还是可以的 如 Color alpha等

    NSLayoutConstraint

    UIButton *button=[[UIButton alloc]init];
    [button setTitle:@"点击一下" forState:UIControlStateNormal];

    button.translatesAutoresizingMaskIntoConstraints=NO;

    [button setBackgroundColor:[UIColor blackColor]];

    [self.view addSubview:button];

    NSArray *constraints1=[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-[button]-|"

    options:0

    metrics:nil

    views:NSDictionaryOfVariableBindings(button)];

    NSArray *constraints2=[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-20-[button(==30)]"

    options:0

    metrics:nil

    views:NSDictionaryOfVariableBindings(button)];


    [self.view addConstraints:constraints1];

    [self.view addConstraints:constraints2];

    九、delegate和Notification的区别?

    delegate针对one-to-one关系,并且reciever可以返回值给sender;

    notification 可以针对one-to-one/many/none,reciever无法返回值给sender;

    所以,delegate用于sender希望接受到reciever的某个功能反馈值,notification用于通知多个object某个事件。

    delegate主动,notification被动

    1.

    Delegate:

    消息的发送者(sender)告知接收者(receiver)某个事件将要发生,delegate同意然后发送者响应事件,delegate机制使得接收者可以改变发送者的行为。通常发送者和接收者的关系是直接的一对多的关系。

    Notification:

    消息的发送者告知接收者事件已经发生或者将要发送,仅此而已,接收者并不能反过来影响发送者的行为。通常发送者和接收者的关系是间接的多对多关系。

    2.

    简单说,

    1. 效率肯定是delegate比nsnotification高。

    2. delegate方法比notification更加直接,最典型的特征是,delegate方法往往需要关注返回值,也就是delegate方法的结果。

    notification

    在IOS应用开发中有一个”Notification Center“的概念。它是一个单例对象,允许当事件发生时通知一些对象。它允许我们在低程度耦合的情况下,满足控制器与一个任意的对象进行通信的目的。这种模式的基本特征是为了让其他的对象能够接收到在该controller中发生某种事件而产生的消息,controller用一个key(通知名称)。这样对于controller来说是匿名的,Source Code其他的使用同样的key来注册了该通知的对象(即观察者)能够对通知的事件作出反应。

    优势:

    1.不需要编写多少代码,实现比较简单;

    2.对于一个发出的通知,多个对象能够做出反应,即1对多的方式实现简单

    3.controller能够传递context对象(dictionary),context对象携带了关于发送通知的自定义的信息

    缺点:

    1.在编译期不会检查通知是否能够被观察者正确的处理;

    2.在释放注册的对象时,需要在通知中心取消注册;

    3.在调试的时候应用的工作以及控制过程难跟踪;

    4.需要第三方对喜爱那个来管理controller与观察者对象之间的联系;

    5.controller和观察者需要提前知道通知名称http://www.androide-apps.com/、UserInfo dictionary keys。如果这些没有在工作区间定义,那么会出现不同步的情况;

    6.通知发出后,controller不能从观察者获得任何的反馈信息。

  • 相关阅读:
    微信公众号 sign类
    serlvet HttpServletRequest
    servlet setCharacterEncoding setHeader 设置字符区别
    java 读取word
    java 使用Java生成word文档
    java io 读取写文件
    异步Promise及Async/Await可能最完整入门攻略
    React和Vue组件间数据传递demo
    Vue基础指令集锦
    vue 关于数组和对象的更新
  • 原文地址:https://www.cnblogs.com/Ruby-Hua/p/5164274.html
Copyright © 2011-2022 走看看