ios 面试题 0

1.__block和__weak修饰符的区别: 

  1.__block不管是ARC还是MRC模式下都可以使用,可以修饰对象,还可以修饰基本数据类型。 
  2.__weak只能在ARC模式下使用,也只能修饰对象(NSString),不能修饰基本数据类型(int)。 
  3.__block对象可以在block中被重新赋值,__weak不可以。 

2.tableView 滑动卡的问题

 主要是因为从缓存中或者是从本地读取图片给UIImage的时候耗费了时间。需要把下面的两句话放到子线程里面:

    1.   NSData *imgData = [NSData dataWithContentsOfURL:[NSURL URLWithString:app.icon]]; //得到图像数据  
    2.      UIImage *image = [UIImage imageWithData:imgData];  

把UIImage赋值给图片的时候在主线程,子线程不能更新UI 所有的UI跟新都是主线程执行了。

3.子线程里面加入NSTimer不能循环怎么解决?

手动添加NSRunloop

4.单例里面添加 NSMutableArray 的时候,怎样防止多个地方对它同时遍历和修改?

需要加原子属性,并且用strong,,,并且写一个遍历和修改的方法。加上锁。   Lock   UnLock  

5.GCD里面怎样 防止内存释放不了,循环引用 ?

__weak ViewController*  weakSelf = self;

6.SDWebImage作用与内部实现过程

作用:可以使用它作为图片异步下载器、图片自动缓存、支持gif动态图等,它会保证相同的url图片资源只下载一次,永远不会锁住主线程,同时支持gcd和arc、arm64。总之,使用SDWebImage下载网络图片可以提高各种性能。

实现过程:首先从缓存里找图片,有就显示;如果没有从磁盘找图片,如果有,将图片添加到内存缓存,显示图片;如果磁盘没有就下载图片,内存和磁盘同时下载,然后显示到界面。

7.http状态码

302 是请求重定向。500以上是服务器错误。400以上是请求链接错误或者找不到服务器。200以上是正确。100以上是请求接受成功。

8.HTTP Keep-Alive是什么?如何工作?

在http早期,每个http请求都要求打开一个tcp socket连接,并且使用一次之后就断开这个tcp连接。
使用keep-alive可以改善这种状态,即在一次TCP连接中可以持续发送多份数据而不会断开连接。更少的tcp连接意味着更少的系统内核调用,socket的accept()和close()调用。
Httpd守护进程,一般都提供了keep-alive timeout时间设置参数。意味着:一个http产生的tcp连接在传送完最后一个响应后,还需要hold住keepalive_timeout秒后,才开始关闭这个连接。
当http的守护进程发送完一个响应后,理应马上主动关闭相应的tcp连接,设置 keep-alive timeout后,httpd守护进程会想说:”再等等吧,看看浏览器还有没有请求过来”,这一等,便是keepalive_timeout时间。如果守护进程在这个等待的时间里,一直没有收到浏览发过来http请求,则关闭这个http连接.

9.GCD的使用

系统给每一个应用程序提供了三个concurrent dispatch queues。这三个并发调度队列是全局的,它们只有优先级的不同。因为是全局的,我们不需要去创建。

1.使用函数dispath_get_global_queue去得到队列,系统默认就有一个串行队列main_queue,以上两个都是全局的队列,不用retain或release。

2.dispatch_group_async是异步的方法,可以实现监听一组任务是否完成,完成后得到通知执行其他的操作。

3.dispatch_barrier_async是在前面的任务执行结束后它才执行,而且它后面的任务等它执行完成之后才会执行

4.dispatch_apply执行某个代码片段N次。
dispatch_apply(5, globalQ, ^(size_t index) {
    // 执行5次

});

10.copy与retain:

1、copy其实是建立了一个相同的对象,而retain不是;
2、copy是内容拷贝,retain是指针拷贝;  
3、copy是内容的拷贝 ,对于像NSString,的确是这样,但是如果copy的是一个NSArray呢?这时只是copy了指向array中相对应元素的指针.这便是所谓的"浅复制".
4、copy的情况:NSString *newPt = [pt copy];
此时会在堆上重新开辟一段内存存放@"abc" 比如0X1122 内容为@"abc 同时会在栈上为newPt分配空间 比如地址:0Xaacc 内容为0X1122 因此retainCount增加1供newPt来管理0X1122这段内存

 11.assign与retain

1、assign: 简单赋值,不更改索引计数;
2、assign的情况:NSString *newPt = [pt assing]; 
此时newPt和pt完全相同 地址都是0Xaaaa 内容为0X1111 即newPt只是pt的别名,对任何一个操作就等于对另一个操作, 因此retainCount不需要增加;
3、assign就是直接赋值;
4、retain使用了引用计数,retain引起引用计数加1, release引起引用计数减1,当引用计数为0时,dealloc函数被调用,内存被回收;    
5、retain的情况:NSString *newPt = [pt retain]; 
此时newPt的地址不再为0Xaaaa,可能为0Xaabb 但是内容依然为0X1111。 因此newPt 和 pt 都可以管理"abc"所在的内存,因此 retainCount需要增加1 ;
12.readonly
属性是只读的,默认的标记是读写,如果你指定了只读,在@implementation中只需要一个读取器。或者如果你使用@synthesize关键字,也是有读取器方法被解析
13.readwrite:
说明属性会被当成读写的,这也是默认属性。设置器和读取器都需要在@implementation中实现。如果使用@synthesize关键字,读取器和设置器都会被解析;
14.nonatomic:
非原子性访问,对属性赋值的时候不加锁,多线程并发访问会提高性能。如果不加此属性,则默认是两个访问方法都为原子型事务访问;
15.weak and strong property (强引用和弱引用的区别):
1、 weak 和 strong 属性只有在你打开ARC时才会被要求使用,这时你是不能使用retain release autorelease 操作的,因为ARC会自动为你做好这些操作,但是你需要在对象属性上使用weak 和strong,其中strong就相当于retain属性,而weak相当于assign。
2、只有一种情况你需要使用weak(默认是strong),就是为了避免retain cycles(就是父类中含有子类{父类retain了子类},子类中又调用了父类{子类又retain了父类},这样都无法release)    
3、声明为weak的指针,指针指向的地址一旦被释放,这些指针都将被赋值为nil。这样的好处能有效的防止野指针。
16. ARC(Automatic Reference Counting):
就是代码中自动加入了retain/release,原先需要手动添加的用来处理内存管理的引用计数的代码可以自动地由编译器完成了。
该机能在 iOS 5/ Mac OS X 10.7 开始导入,利用 Xcode4.2 以后可以使用该特性。
17.strong,weak,copy 具体用法:strong,weak,copy 具体用法:
1.具体一点:IBOutlet可以为weak,NSString为copy,Delegate一般为weak,其他的看情况。一般来说,类“内部”的属性设置为strong,类“外部”的属性设置为weak。说到底就是一个归属权的问题。小心出现循环引用导致内存无法释放。
2.不用ARC的话就会看到很多retian。
3.如果你写了@synthesize abc = _abc;的话,系统自动帮你声明了一个_abc的实例变量。
   使用assign: 对基础数据类型 (NSInteger)和C数据类型(int, float, double, char,等)
   使用copy: 对NSString  
 使用retain: 对其他NSObject和其子类 
18.写一个NSString类的实现

+ (id)initWithCString:(c*****t char *)nullTerminatedCString encoding:(NSStringEncoding)encoding; 

+ (id) stringWithCString: (c*****t char*)nullTerminatedCString  

            encoding: (NSStringEncoding)encoding 

  NSString  *obj; 

  obj = [self allocWithZone: NSDefaultMallocZone()]; 

  obj = [obj initWithCString: nullTerminatedCString encoding: encoding]; 

  return AUTORELEASE(obj); 

19.static 关键字的作用: 

(1)函数体内 static 变量的作用范围为该函数体,不同于 auto 变量,该变量的内存只被分配一次, 

因此其值在下次调用时仍维持上次的值; 

(2)在模块内的 static 全局变量可以被模块内所用函数访问,但不能被模块外其它函数访问; 

(3)在模块内的 static 函数只可被这一模块内的其它函数调用,这个函数的使用范围被限制在声明 

它的模块内; 

(4)在类中的 static 成员变量属于整个类所拥有,对类的所有对象只有一份拷贝; 

(5)在类中的 static 成员函数属于整个类所拥有,这个函数不接收 this 指针,因而只能访问类的static 成员变量。

20.线程与进程的区别和联系? 

进程和线程都是由操作系统所体会的程序运行的基本单元,系统利用该基本单元实现系统对应用的并发性。 

程和线程的主要差别在于它们是不同的操作系统资源管理方式。进程有独立的地址空间,一个进程崩溃后,在保护模式下不会对其它进程产生影响,而线程只是一个进程中的不同执行路径。线程有自己的堆栈和局部变量,但线程之间没有单独的地址空间,一个线程死掉就等于整个进程死掉,所以多进程的程序要比多线程的程序健壮,但在进程切换时,耗费资源较大,效率要差一些。但对于一些要求同时进行并且又要共享某些变量的并发操作,只能用线程,不能用进程。

posted @ 2016-04-08 15:01  Bo-tree  阅读(141)  评论(0编辑  收藏  举报