为什么说Objective-C是一门动态的语言
因为在OC中,对于数据类型(数据类型包括类和数据变量)的确认并不是在编译器,而是在运行期。在OC的底层实现里面,使用到了Runtime运行时系统,这是一个C语言的库,OC在编译期的时候,将OC的消息转换成C语言的函数,并且在运行期的时候,可以动态的创建新类,在类里面添加方法,实例变量,属性等等。所以说OC是一门动态语言。
讲一下MVC和MVVM,MVP?
MVC设计模式:采用设计模式,个人觉得主要原因是为了解耦,方便复用和管理。MVC简单来讲分为了三层:M是model层,V是View层,C是controller是用来连接model和view之间的桥梁。
MVVM设计模式:采用MVC设计模式时,因为有些处理,比如网络请求,数据的处理等一些业务逻辑的处理,我们放在VC里面。时间长了之后就会造成VC臃肿,可以把这上面这些业务逻辑提取出来,放到对应的viewmodel中,这种model,view,viewmodel的设计模式,叫做MVVM设计模式。
MVVM特点:
- 解耦合 view层只是单纯的显示,可以独立于model变化和修改。一个viewModel可以绑定到多个不同的view上。当view变化的时候,model可以不变,当model变化的时候,view也可以不变。
- 可重用 可以把一些视图的逻辑,放在viewmodel里面,让很多view可以重用这段视图逻辑。
- 独立开发 开发人员可以更专注于业务逻辑和数据的开发。设计人员可以专注设计界面。
可测试性 可以针对viewmodel来对页面进行测试。
MVP设计模式:MVP设计模式不好说
为什么代理要用weak?代理的delegate和dataSource有什么区别?block和代理的区别?
代理使用weak是为了避免循环引用。 代理的delegate一般是把被委托的对象的消息传给委托对象。 dataSource 一般是委托对象把数据信息传递给委托对象。举例说明就是我们创建了A对象,如果B对象实现了A的代理方法,那么代理可以让A通知B对象,A对象发生了什么变换。
如果A对象声明了数据源方法,并且B对象实现了A的数据源方法,那么在B中就可以通过数据源方法告诉A,B给A传了哪些数据。总结就是代理方法一般没有返回值,数据源方法有返回值。
代理和Block的区别
从相同点来说:代理是block都是用来实现反向船传值的。都需要注意循环引用的问题。
不同点:代理需要用weak来修饰,避免循环引用。使用代理,必须先声明代理方法,调用代理的时候,要判断代理方法是否已经实现。block是用copy修饰,block是一个匿名函数。能捕获其所在作用域里面的所有变量,并进行拷贝。使用block也要判断是否实现。
属性的实质是什么?包括哪几个部分?属性默认的关键字都有哪些?@dynamic关键字和@synthesize关键字是用来做什么的?
属性其实就是对数据的封装,property = iva + setter + getter .
属性默认的关键字:
- 如果是基本数据类型: atomic,assign,readwrite
- 如果是对象类型: atomic,strong,readwrite
dynamic关键字的意思是手动添加setter和getter方法。
- synthesize关键字的意思是编译器自动生成setter和getter方法,并可以指定与属性相对应的成员变量。
NSString为什么要用copy关键字,如果用strong会有什么问题?
因为NSString有对应的NSMutableString类型,并且NSString 类型的指针可以指向NSMutableString类型。因为copy关键字,返回的类型都是不可变对象。所以,使用关键字,可以保证NSString类型都会变成不可修改的。
如果使用strong关键字,只是指针赋值,栈中的对象的引用计数加一,如果把一个可变字符串赋值给NSString,NSString就会变成可变类型。- 如何令自己所写的对象具有拷贝功能?
如果想实现不可变的拷贝,需要遵守NSCopying协议,如果可变和不可变都想实现,需要同时遵守NSCopying和NSMutableCopying协议。并且实现- (id)copyWithZone:(NSZone *)zone;
- 如何令自己所写的对象具有拷贝功能?
可变集合类 和 不可变集合类的 copy 和 mutablecopy有什么区别?如果是集合是内容复制的话,集合里面的元素也是内容复制么?
- 可变集合类 : copy 后返回的是不可变集合对象,属于深拷贝。mutableCopy之后返回的是可变集合对象,属于深拷贝。。
不可变集合类 : copy 返回的是不可变集合对象,属于浅拷贝。mutableCopy之后返回的是可变集合对象,属于深拷贝。
如过集合是内容复制的话,集合里面的元素是前拷贝,属于指针复制。
为什么IBOutlet修饰的UIView也适用weak关键字?
因为使用IBOultlet修饰的UIView,自身已经强引用过,所以,用可以用weak关键字来修饰。
nonatomic和atomic的区别?atomic是绝对的线程安全么?为什么?如果不是,那应该如何实现?
nonatomic和atomic的区别?atomic是绝对的线程安全么?为什么?如果不是,那应该如何实现?
nonatomic 对属性来说是非原子操作,atomic对属性来说是原子操作。atomic虽然是原子操作,但是并不是线程安全的。因为多线程同时访问的时候,会造成线程不安全。
所以可以使用线程锁或者GCD来保证线程安全。例子:
UICollectionView自定义layout如何实现?
实现一个自定义的layout,需要继承UICollectionViewLayout类,然后重载下列方法:-(CGSize)collectionViewContentSize //返回collectionView的内容的尺寸
-(NSArray *)layoutAttributesForElementsInRect:(CGRect)rect //返回rect中的所有的元素的布局属性
用StoryBoard开发界面有什么弊端?如何避免?
简单的逻辑页面的跳转可以使用sb,开发比较快。但是复杂的页面不适合用sb开发,并且不适合多人开发;不利于后期版本维护和更新。使用sb在项目编译的时候会加载到内存中,造成内存浪费。
可以使用xib来代替,编写复杂页面逻辑的时候,可以采用纯代码编写。
进程和线程的区别?同步和异步的区别,并行和并发的区别?
进程: 一个APP,一个应用软件的开启,就是一个进程。进程是系统进行资源分配和调度的一个独立单位。
线程:线程是CPU调度和分派的基本单位,是比进程更小的独立运行的基本单位。
同步:阻塞当前线程操作,不能开辟线程。
异步:不阻碍当前线程,开辟新的线程来执行任务。并行:多个cpu,多个线程
并发: 一个cpu,多个线程线程间通信
拿GCD来说,当使用dispatch_async函数开辟线程执行任务完成时,需要使用dispatch_async(dispatch_get_main_queue(),^{})函数来刷新UI,并完成通信。GCD的一些常用的函数?(group,barrier,信号量,线程同步)
同步,异步,串行,并行。
同步函数是dispatch_sync,异步函数是dispatch_async.
同步函数和异步函数可以把block任务放在串行队列或者并行队列之中。group函数,举个例子,下载多张小图,最后合成一张大图。因为下载小图需要开启多个线程,需要所有的线程执行完毕之后,在进行合成,用group就是可以在多个线程执行得到通知。
barrier 栅栏函数,在一组异步形成里面,添加栅栏函数,只有栅栏函数前面的函数执行完毕之后,才能在执行栅栏函数后面的异步线程。
信号量:这个比较难不好说。
- 如何使用队列来避免资源抢夺?
使用队列来避免资源抢夺: 可以使用串行队列来避免资源抢夺,也可以使用并行队列来避免资源抢夺。 数据持久化的几个方案(fmdb用没用过)
持久化方案:
plist,存储字典,数组
preference:偏好设置,实质也是plist
NSKeyedArchiver:归档,可以存储对象。
sqlite:数据库,经常使用FMDB
coreData:苹果官方提供的数据库存储- 说一下appdelegate的几个方法?从后台到前台调用了哪些方法?第一次启动调用了哪些方法?从前台到后台调用了哪些方法?