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):连接视图类和模型类,任务是使数据显示在屏幕上。
MVVM全名是Model View View-Model,ViewModel将表示逻辑从 Controller 移出放到一个新的对象里,即 View Model。就是那些将 Model 数据转换为 View 可以呈现的东西的事情,例如将一个 NSDate 转换为一个格式化过的 NSString。
MVP全名是Model-view-presenter,是使用者界面设计模式的一种。
Model 定义使用者界面所需要被显示的数据模型,一个模型包含着相关的业务逻辑。
View 视图为呈现使用者界面的终端,用以表现来自 Model 的数据,和使用者命令路由再经过 Presenter 对事件处理后的数据。
Presenter 包含着元件的事件处理,负责检索 Model 取得数据,和将取得的数据经过格式转换与 View 进行沟通。
MVP 设计模式通常会再加上 Controller 做为整体应用程序的后端程序工作。
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和代理的区别?
4、属性的实质是什么?包括哪几个部分?属性默认的关键字都有哪些?@dynamic关键字和@synthesize关键字是用来做什么的?
1)属性的实质是什么?包括哪几个部分
@property = ivar + getter + setter;
利用class_copyPropertyList 查看类的所有属性
利用class_copyIvarList查看类的所有成员变量
利用class_copyMethodList查看类的所有方法
2)属性默认的关键字都有哪些?
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.)如何实现线程安全
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用没用过)
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的几点?
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?什么应用场景?
类结构
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)