美文网首页
2019 iOS面试资料

2019 iOS面试资料

作者: Lightoflife | 来源:发表于2019-02-20 23:02 被阅读0次

    1、我们说的Objective-C是动态运行时语言是什么意思?

    答:oc类的类型和数据变量的类型都是在运行时确定的,而不是在编译时确定的,所以说oc是动态语言。

    它主要表现在三个方面:

    1、动态类型:

    即运行时再决定对象的类型。比如id类型,任何对象都可以被id指针所指,只有在运行时才能决定是什么类型。像内置的明确的基本类型都属于静态类型(int、NSString等)。静态类型在编 译的时候就能被识别出来。所以,若程序发生了类型不对应,编译器就会发出警告。而动态类型就编译器编译的时候是不能被识别的,要等到运行时(run time),即程序运行的时候才会根据语境来识别。

    2.动态绑定:

    基于动态类型,在某个实例对象被确定后,其类型便被确定了。该对象对应的属性和响应的消息也被完全确定,也就是说让代码在运行时判断需要调用什么方法,而不是在编译时,这就是动态绑定。比如我们一般向一个NSObject对象发送-respondsToSelector:或者 -instancesRespondToSelector:等来确定对象是否可以对某个SEL做出响应,而在OC消息转发机制被触发之前,对应的类 的+resolveClassMethod:和+resolveInstanceMethod:将会被调用,在此时有机会动态地向类或者实例添加新的方 法,也即类的实现是可以动态绑定的;isKindOfClass也是一样的道理。

    3.动态加载:

    根据需求加载所需要的资源,这点很容易理解,对于iOS开发来说,基本就是根据不同的机型做适配。最经典的例子就是在Retina设备上加载@2x的图片,而在老一些的普通屏设备上加载原图

    2、讲一下MVC和MVVM,MVP?

    MVC全名是Model View Controller,是模型(model)-视图(view)-控制器(controller)的缩写,Model 呈现数据,View 呈现用户界面,而 View Controller 调节它两者之间的交互。

    视图(View):构建UI的类;例如:按钮,标签,进度条等。

    模型(Model):视图类所需要的数据;例如:表格需要显示的文字。

    控制器(Controller):连接视图类和模型类,任务是使数据显示在屏幕上。

    MVC

    MVVM全名是Model View View-Model,ViewModel将表示逻辑从 Controller 移出放到一个新的对象里,即 View Model。就是那些将 Model 数据转换为 View 可以呈现的东西的事情,例如将一个 NSDate 转换为一个格式化过的 NSString。

    MVVM

    MVP全名是Model-view-presenter,是使用者界面设计模式的一种。

    Model 定义使用者界面所需要被显示的数据模型,一个模型包含着相关的业务逻辑。

    View 视图为呈现使用者界面的终端,用以表现来自 Model 的数据,和使用者命令路由再经过 Presenter 对事件处理后的数据。

    Presenter 包含着元件的事件处理,负责检索 Model 取得数据,和将取得的数据经过格式转换与 View 进行沟通。

    MVP 设计模式通常会再加上 Controller 做为整体应用程序的后端程序工作。

    MVP

    3、为什么代理要用weak?代理的delegate和dataSource有什么区别?block和代理的区别?

    1)为什么代理要用weak?

       防止循环引用。例如View有一个协议,需要一个代理实现回调。一个Controller添加这个View,并且遵守协议,成为View的代理。如果不用week,用strong,Controller ->View -> delegate -> Controller,就循环引用了。

    2)代理的delegate和dataSource有什么区别?

       delegate偏重于与用户交互的回调,有那些方法可以供我使用,例如UITableviewDelegate;dataSource偏重于数据的回调,view里面有什么东西,属性都是什么,例如UITableviewDatasource;

    3) block和代理的区别?

    block和delegate的区别

    4、属性的实质是什么?包括哪几个部分?属性默认的关键字都有哪些?@dynamic关键字和@synthesize关键字是用来做什么的?

    1)属性的实质是什么?包括哪几个部分

    @property = ivar + getter + setter;

    利用class_copyPropertyList 查看类的所有属性

    利用class_copyIvarList查看类的所有成员变量

    利用class_copyMethodList查看类的所有方法

    2)属性默认的关键字都有哪些?

    iOS关于属性关键字,你又知道多少?

    3) @dynamic关键字

    @dynamic告诉编译器,属性的setter与getter方法由用户自己实现。

    4) @synthesize关键字

    @synthesize的语义是如果你没有手动实现setter方法和getter方法,那么编译器会自动为你加上这两个方法。

    5、属性的默认关键字是什么?

    readwrite、nonatomic、strong

    6、NSString为什么要用copy关键字,如果用strong会有什么问题?(注意:这里没有说用strong就一定不行。使用copy和strong是看情况而定的)

    1) 因为父类指针可以指向子类对象,使用copy的目的是为了让本对象的属性不受外界影响,使用copy无论给我传入是一个可变对象还是不可对象,我本身持有的就是一个不可变的副本.

    2)如果我们使用是strong,那么这个属性就有可能指向一个可变对象,如果这个可变对象在外部被修改了,那么会影响该属性.

    7、如何令自己所写的对象具有拷贝功能?

    答:若想令自己所写的对象具有拷贝功能,则需实现 NSCopying 协议。如果自定义的对象分为可变版本与不可变版本,那么就要同时实现 NSCopying与 NSMutableCopying协议。

    具体步骤:

    需声明该类遵从 NSCopying 协议

    实现 NSCopying 协议。该协议只有一个方法:

    - (id)copyWithZone:(NSZone*)zone;

    8、简述kvo、kvc、Delegate他们之间的区别?

    简述NotificationCenter,KVC,KVO,delegate,并说明他们之间的区别

    9、include与#import的区别?#import与@class的区别?

    1)两者的区别是:#include与#import的效果相同,只是后者不会引起交叉编译,确保头文件只会被导入一次。

    2)#import与@class的却别是:#import会包含这个类的所有信息,包括实体变量和方法,而@class只是告诉编译器,其后面声明的名称是类的名称,至于这些类是如何定义的,暂时不用考虑。使用#import编译效果高,防止相互包含的编译错误。

    10、nonatomic和atomic的区别?atomic是绝对的线程安全么?为什么?如果不是,那应该如何实现?

    1)nonatomic和atomic的区别

    nonatomic和atomic用来决定编译器生成的getter和setter操作是否为原子操作。

    2)atomic是绝对的线程安全么?

    atomic不是绝对的线程安全。atomic的本意是指属性的存取方法是线程安全的,并不保证整个对象是线程安全的。如:

    声明一个NSMutableArray的原子属性stuff,此时self.stuff 和 self.stuff = otherstuff都是线程安全的。但是使用[self.stuff objectAtIndex:index]就不是线程安全的。需要用互斥锁来保证线程安全性。

    3.)如何实现线程安全

    iOS中保证线程安全的几种方式与性能对比

    11、Objective-C与C、C+++之间的联系和区别?

    C语言的特点:

    1)C语言是结构化语言,层次清晰,调试和维护比较容易

    2)表现能力和处理能力比较强,可直接访问内存的物理地址

    3)c语言实现对硬件的编辑,c语言课用语系统软件的开发,也可用语应用软件的开发,是集高级语言和低级语言的功能一体。

    4)C语言效率高,可移植性强。

    C++语言特点:

    1)在C语言的基础上进行扩充和完善,使C++兼容了C语言的面向过程特点,又成为了一种面向对象的程序设计语言;

    2)可以使用抽象数据类型进行基于对象的编程;

    3)可以使用多继承、多态进行面向对象的编程;

    4)可以担负起以模版为特征的泛型化编程。

    OC的特点:

    2)Objective-C,扩展了C 语言使它具备面向对象设计的能力,例如类、消息、继承;同时在Objective-C的代码中可以有C和C++语句,它可以调用C的函数,也可以通过C++对象访问方法;

    3)Objective-C可以实现底层系统编程,另一方面可以支持利用动态架构进行开发。

    OC与C语言的区别

    OC里中兼容C语言的语法可以两者混合编码。 OC是面向对象的,有类,对象的概念,C语言没有

    C是面向过程的语言

    OC的和C++的区别:

    1)继承:Objective-C与不支持多重继承,而C++语言支持多重继承(从侧面可以说明多重继承的效率不高);

    2)函数调用:Objective-C通过互相传递消息实现函数调用,而C++直接进行函数调用

    3)定型:Objective-C是动态定型。所以它的类库比C++要容易操作。Objective-C 在运行时可以允许根据字符串名字来访问方法和类,还可以动态连接和添加类。而C++,对象的静态类型决定你是否可以发送消息给它。

    4)接口:Objective-C采用protocol协议(非正式和正式)的形式来定义接口,而C++采用虚函数的形式来定义接口。

    5)方法重载:c++中允许两个方法的名字相同,参数个数相同,但是参数类型不同,以及不同的返回值类型。而OC中不允许同一个类中两个方法有相同的名字,参数个数相同,参数类型不同。

    链接:https://www.jianshu.com/p/0417d5c01380

    12、UICollectionView自定义layout如何实现?

    其实可以分三个步骤:

    1)覆写prepareLayout方法,并在里面事先就计算好必要的布局信息并存储起来。

    2)基于prepareLayout方法中的布局信息,使用collectionViewContentSize方法返回UICollectionView的内容尺寸。

    3)使用layoutAttributesForElementsInRect:方法返回指定区域cell、Supplementary View和Decoration View的布局属性。

    13、进程和线程的区别?同步异步的区别?并行和并发的区别?

    一、线程与进程的区别

    进程:指内存中所运行的程序

    线程:进程中的一个执行流

    区别:

    1、一个程序至少有一个进程(当然也可以启动多个进程),而一个进程至少有一个线程(当然也可以多个线程同时运行,如果支持的话)

    2、另外,内存中的每一个进程都是有独立内存单元的(进程是可以申请系统资源的),而其中的多个线程是可以共享内存的(共享其所在进程的资源),可以提高程序运行效率

    3、进程是一个“执行中的程序”。

    4、子进程和父进程具有不同的代码和数据空间,而多个线程则是共享数据空间。多线程是为了节约CPU时间,充分发挥系统的“空闲时间”。

    二、并发与并行的区别

    并发:指一个时间段中几个程序都处于已启动到运行完毕之间。(可能现在并没有在工作),且这几个程序都是在同一个处理机上运行。

    并行:并行是针对多处理器而言的(当然,单处理器也可以表现出并行的状态,主要表现为进程被交替执行)。指同时发生多个并发事件(但是并发不一定并行,或者说并发事件之间不一定要同一时刻发生),主要表现为重叠执行。

    三、同步和异步

    同步和异步是相对表现的,通俗点,同步就是顺序执行,执行完当前的任务再执行下一个,需要等待、协调运行。而异步就是彼此独立,多个任务之间不必要互相等待,只要CPU空闲,就可以同时执行多个任务,不需要等待其它任务的完成。而我们平时所说的线程,就是实现异步的一个手段而已。

    原文:https://blog.csdn.net/lw1352617612/article/details/74157053

    14、线程间通信?

    线程间通信:在1个进程中,线程往往不是孤立存在的,多个线程之间需要经常进行通信

    线程间通信的体现

    1个线程传递数据给另1个线程

    在1个线程中执行完特定任务后,转到另1个线程继续执行任务

    线程间通信常用方法

    - (void)performSelectorOnMainThread:(SEL)aSelector withObject:(id)arg waitUntilDone:(BOOL)wait;

    - (void)performSelector:(SEL)aSelector onThread:(NSThread *)thr withObject:(id)arg waitUntilDone:(BOOL)wait;

    15、GCD的一些常用的函数?(group,barrier,信号量,线程同步)

    线程间通信示例 – 图片下载

    16、如何访问并修改一个类的私有属性?

    答:KVC,setvalue: forkey:方法修改

    17、数据持久化的几个方案(fmdb用没用过)

    我要永远地记住你!(iOS中几种数据持久化方案)

    18、说一下AppDelegate的几个方法?从后台到前台调用了哪些方法?第一次启动调用了哪些方法?从前台到后台调用了哪些方法?

    1.点击App图标(App没有在后台运行)

    1)didFinishLaunchingWithOptions

    2)applicationDidBecomeActive

    2.从后台到前台

    1)applicationWillEnterForeground

    2)applicationDidBecomeActive

    3.从前台到后台

    1)applicationWillResignActive

    2)applicationDidEnterBackground

    4.通过URLScheme打开App

    1.applicationWillEnterForeground

    2.

    - (BOOL)application:(UIApplication*)application                    

                    openURL:(NSURL*)url  

                 sourceApplication:(NSString*)sourceApplication 

                   annotation:(id)annotation

      3.applicationDidBecomeActive

    19、NSCache优于NSDictionary的几点?

    对NSCache的一些理解...

    20、知不知道Designated Initializer?使用它的时候有什么需要注意的问题?

    我也不知道是啥

    21、实现description方法能取到什么效果?

    description基本概念

    1.NSLog(@"%@", objectA);这会自动调用objectA的description方法来输出ObjectA的描述信息.

    2.description方法默认返回对象的描述信息(默认实现是返回类名和对象的内存地址)

    3.description方法是基类NSObject 所带的方法,因为其默认实现是返回类名和对象的内存地址, 这样的话,使用NSLog输出OC对象,意义就不是很大,因为我们并不关心对象的内存地址,比较关心的是对象内部的一些成变量的值。因此,会经常重写description方法,覆盖description方法 的默认实现

    description重写的方法

    /**对象方法:当使用NSLog输出该类的实例对象的时候调用*/

    -(NSString *) description

    {

    return [NSString stringWithFormat:@"狗腿数:%d,狗眼数%d\n",_legNum,_eyeNum];

    }

    /**类方法:当使用NSLog输出该类的类对象的时候调用*/

    +(NSString *) description

    {

    return @"+开头的description方法";

    }

    description陷阱

    1.千万不要在description方法中同时使用%@和self,下面的写法是错误的

    - (NSString *)description {

    return [NSString stringWithFormat:@"%@", self];

    }

    2.同时使用了%@和self,代表要调用self的description方法,因此最终会导致程序陷入死循环,循 环调用description方法

    3.当[NSString stringWithFormat:@“%@”, self]; 使用它时,循坏调用,导致系统会发生运行时错误。

    4.当该方法使用NSLog(“%@”,self) 时候, 系统做了相关的优化,循坏调用3次后就会自动退出

    22、objc使用什么机制管理对象内存?

    MRC(手动管理内存)、ARC(自动管理内存)

    中级Block

    1、block的实质是什么?一共有几种block?都是什么情况下生成的?

    A:block对象就是一个结构体,里面有isa指针指向自己的类(global malloc stack),有desc结构体描述block的信息,__forwarding指向自己或堆上自己的地址,如果block对象截获变量,这些变量也会出现在block结构体中。最重要的block结构体有一个函数指针,指向block代码块。block结构体的构造函数的参数,包括函数指针,描述block的结构体,自动截获的变量(全局变量不用截获),引用到的__block变量。(__block对象也会转变成结构体)

    block代码块在编译的时候会生成一个函数,函数第一个参数是前面说到的block对象结构体指针。执行block,相当于执行block里面__forwarding里面的函数指针。

    2、使用系统的某些block api,是否考虑引用循环问题?

    使用系统的某些block api(如UIView的block版本写动画时),是否也考虑引用循环问题?...

    3、谈谈block的理解?并写出一个使用block执行UIVew动画?

    Block是可以获取其他函数局部变量的匿名函数,其不但方便开发,并且可以大幅提高应用的执行效率(多核心CPU可直接处理Block指令)

    [UIView transitionWithView:self.view  

                      duration:0.2  

                       options:UIViewAnimationOptionTransitionFlipFromLeft  

                    animations:^{ [[blueViewController view] removeFromSuperview]; [[self view] insertSubview:yellowViewController.view atIndex:0]; }  

    completion:NULL]; 

    Runtime

    1、runtime如何实现weak属性?

    1)要实现 weak 属性,首先要搞清楚 weak 属性的特点:

    weak 此特质表明该属性定义了一种“非拥有关系” (nonowning relationship)。为这种属性设置新值时,设置方法既不保留新值,也不释放旧值。此特质同 assign 类似, 然而在属性所指的对象遭到摧毁时,属性值也会清空(nil out)。

    2)那么 runtime 如何实现 weak 变量的自动置nil?

    runtime 对注册的类, 会进行布局,对于 weak 对象会放入一个 hash 表中。 用 weak 指向的对象内存地址作为 key,当此对象的引用计数为0的时候会 dealloc,假如 weak 指向的对象内存地址是a,那么就会以a为键, 在这个 weak 表中搜索,找到所有以a为键的 weak 对象,从而设置为 nil。

    2、runtime如何通过selector找到对应的IMP地址?

    每一个类对象中都一个对象方法列表(对象方法缓存)

    1)类方法列表是存放在类对象中isa指针指向的元类对象中(类方法缓存)

    2)方法列表中每个方法结构体中记录着方法的名称,方法实现,以及参数类型,其实selector本质就是方法名称,通过这个方法名称就可以在方法列表中找到对应的方法实现.

    3)当我们发送一个消息给一个NSObject对象时,这条消息会在对象的类对象方法列表里查找

    4)当我们发送一个消息给一个类时,这条消息会在类的Meta Class对象的方法列表里查找

    3、能否向编译后得到的类中增加实例变量?能否向运行时创建的类中添加实例变量?为什么?

    不能向编译后得到的类中增加实例变量;

    能向运行时创建的类中添加实例变量;

    原因如下:

    因为编译后的类已经注册在 runtime 中,类结构体中的 objc_ivar_list 实例变量的链表 和 instance_size 实例变量的内存大小已经确定,同时runtime 会调用 class_setIvarLayout 或 class_setWeakIvarLayout 来处理 strong weak 引用。所以不能向存在的类中添加实例变量;

    运行时创建的类是可以添加实例变量,调用 class_addIvar 函数。但是得在调用 objc_allocateClassPair 之后,objc_registerClassPair 之前,原因同上。

    4、runtime如何实现weak变量的自动置nil?

    5、在开发中如何使用runtime?什么应用场景?

    在开发中如何使用runtime?什么应用场景?

    类结构

    1、isa指针?(对象的isa,类对象的isa,元类的isa都要说)

    2、类方法和实例方法有什么区别?

    3、介绍一下分类,能用分类做什么?内部是如何实现的?它为什么会覆盖掉原来的方法?

    4、运行时能增加成员变量么?能增加属性么?如果能,如何增加?如果不能,为什么?

    5、objc中向一个nil对象发送消息将会发生什么?(返回值是对象,是标量,结构体)

    高级

    1、UITableview的优化方法(缓存高度,异步绘制,减少层级,hide,避免离屏渲染)

    2、有没有用过运行时,用它都能做什么?(交换方法,创建类,给新创建的类增加方法,改变isa指针)

    3、看过哪些第三方框架的源码?都是如何实现的?(如果没有,问一下多图下载的设计)

    4、SDWebImage的缓存策略?

    5、AFN为什么添加一条常驻线程?

    6、KVO的使用?实现原理?(为什么要创建子类来实现)

    7、KVC的使用?实现原理?(KVC拿到key以后,是如何赋值的?知不知道集合操作符,能不能访问私有属性,能不能直接访问_ivar)

    相关文章

      网友评论

          本文标题:2019 iOS面试资料

          本文链接:https://www.haomeiwen.com/subject/zlbkyqtx.html