iOS常考9大题

一.类别和类扩展的区别

  1.类别(Category)是一种可以为现有的类,添加新方法的方式无需从现有的类继承子类。类别添加的新方法可以被子类继承。

  注:继承(inheritance)无法为一个类簇创建子类。类别不能添加实例变量。

 

类别的局限性

   ①无法向现有的类中添加新的实例变量(类别没有位置容纳实例变量);   

   ②方法名称冲突,即类别中的新方法的名称与现有类中方法名称重名,类别具有更高的优先级,类别中的方法将完全取代现有类中的方法(再也无法访问现有类中的同名方法)。

  

2.类扩展声明格式@interface MyClass(), 可以在类扩展中声明属性和实例变量。

一.类别和类扩展的区别 

二.什么是KVC和KVO

1.Key-Value Coding (KVC)

KVC,即是指 NSKeyValueCoding,一个非正式的 Protocol,提供一种机制来间接访问对象的属性。KVO 就是基于 KVC 实现的关键技术之一。

一个对象拥有某些属性。比如说,一个 Person 对象有一个name 和一个 address 属性。以 KVC 说法,Person 对象分别有一个 value 对应他的 name 和 address 的key。 key 只是一个字符串,它对应的值可以是任意类型的对象。从最基础的层次上看,KVC 有两个方法:一个是设置 key 的值,另一个是获取 key 的值。

2.Key-Value Observing (KVO) 建立在 KVC 之上,它能够观察一个对象的 KVC key path 值的变化。举个例子,用代码观察一个 person 对象的 address 变化,以下是实现的三个方法:

?        watchPersonForChangeOfAddress:实现观察

?        observeValueForKeyPath:ofObject:change:context:在被观察的 key path 的值变化时调用。

?        dealloc 停止观察

 

三.浅复制和深复制的区别

浅层复制(copy):只复制指向对象的指针,而不复制引用对象本身。//通过对象的指针来访问这个对象深层复制(mutableCopy):复制引用对象本身意思就是有个A对象,复制一份后得到A_copy对象后,对于浅复制来说,A和A_copy指向的是同一个内存资源,复制的只不过是是一个指针,对象本身资源还是只有一份,那如果我们对A_copy执行了修改操作,那么发现A引用的对象同样被修改,这其实违背了我们复制拷贝的一个思想。深复制就好理解了,内存中存在了两份独立对象本身。//当修改A时,A copy不变。

四. 什么是id类型

id类型的变量可以存放任何数据类型的对象。在内部处理上,这种类型被定义为指向对象的指针,实际上是一个指向这种对象的实例变量的指针。例如:id number将number声明为id类型的变量。可声明的方法使其具有id类型的返回值,如下:-(id)newObject;(int)type;这个程序声明了一个名为newObject的实例方法,它具有名为type的单个整型参数并有id类型的返回值。应该注意的是,对返回值和参数类型声明来说,id是默认的类型。id类型是objetive-c中非常中药店额数据类型,它是多态和动态绑定的基础。


五. 介绍下NSOperation队列

操作和操作队列,基本可以看成java中的线程和线程池的概念。用于处理ios多线程开发的问题。网上部分资料提到一点是,虽然是queue,但是却并不是带有队列的概念,放入的操作并非是按照严格的先进现出。这边又有个疑点是,对于队列来说,先进先出的概念是Afunc添加进队列,Bfunc紧跟着也进入队列,Afunc先执行这个是必然的,但是Bfunc是等Afunc完全操作完以后,B才开始启动并且执行,因此队列的概念离乱上有点违背了多线程处理这个概念。但是转念一想其实可以参考银行的取票和叫号系统。因此对于A比B先排队取票但是B率先执行完操作,我们亦然可以感性认为这还是一个队列。但是后来看到一票关于这操作队列话题的文章,其中有一句提到?“因为两个操作提交的时间间隔很近,线程池中的线程,谁先启动是不定的。”?瞬间觉得这个queue名字有点忽悠人了,还不如pool~综合一点,我们知道他可以比较大的用处在于可以帮组多线程编程就好了。


六.说说事件响应链

      事件响应链。包括点击事件,画面刷新事件等。在视图栈内从上至下,或者从下之上传播。



七.代码实现一个retain的方法

@property(nonamtic,retain)NSString *var;

这时,自动生成的Setter方法是这样的:

-(void)Setter:(NSString*)str

  [str retain];

  [var release];

  var=str;

var=[[NSString alloc]initWithString: @"aaa"];

NSLog(@%d,[var retainCount]);  输出值

 

self.var=[[NSString alloc]initWithString:@"aaa"];

NSLog(@%d,[var retainCount]);  输出值

 

 


八.iOS多线程保护全局变量实现方法有哪些

第1种,使用@synchronized(self)

@synchronized(self)

{?    保护的变量?     }

作用:创建了一个互斥锁,它的作用和其他语言中的互斥锁作用一样

解释:这个是Objective-C中的一个锁定令牌,方便一个对象在同一时间内被其他线程访问,起到了线程保护的作用

第2种,使用GCD    

   static dispatch_once_t onceToken;?   

dispatch_once(&onceToken, ^{

        保护的变量?  

  });}

第3种,使用NSOperationQueue

NSOperationQueue *onceToken=[[NSOperationQueue alloc]init];?   

 [onceTokenaddOperationWithBlock:^(){?  

   保护的变量

   });

九、简述下ViewController的loadView,vewDidLoad,viewDidUnload分别在什么时候调用,在自定义ViewController的时候这几个函数里面应该做什么工作?

1.第一次访问UIViewController的view时,view为nil,然后就会调用loadView方法创建view

2.view创建完毕后会调用viewDidLoad方法进行界面元素的初始化

3.当内存警告时,系统可能会释放UIViewController的view,将view赋值为nil,并且调用viewDidUnload方法

4.当再次访问UIViewController的view时,view已经在3中被赋值为nil,所以又会调用loadView方法重新创建view

5.view被重新创建完毕后,还是会调用viewDidLoad方法进行界面元素的初始化

 

 

loadView

1.什么时候被调用?

每次访问UIViewController的view(比如controller.view、self.view)而且view为nil,loadView方法就会被调用。

2.有什么作用?

loadView方法是用来负责创建UIViewController的view

viewDidLoad

1.什么时候被调用?

不过你是通过xib文件还是重写loadView创建UIViewController的view,在view创建完毕后,最终都会调用viewDidLoad方法

2.有什么作用?

一般我们会在这里做界面上的初始化操作,比如往view中添加一些子视图、从数据库或者网络加载模型数据装配到子视图中

viewDidUnload

1.什么时候被调用?

iOS设备的内存是极其有限的,如果应用程序占用的内存过多的话,系统就会对应用程序发出内存警告。UIViewController就会收到didReceiveMemoryWarning消息。didReceiveMemoryWarning方法的默认实现是:如果当前UIViewController的view不在应用程序的视图层次结构(View Hierarchy)中,即view的superview为nil的时候,就会将view释放,并且调用viewDidUnload方法

2.有什么作用?

上面说到,发出内存警告且view被释放的时候就会调用viewDidUnload方法,所以一般在释放资源,主要是释放界面元素相关的资源,将相关的实例都赋值为nil

 

iOS常考9大题

上一篇:后端Spring Boot+前端Android交互+MySQL增删查改


下一篇:hadoop2.2稳定版本新特性