1.__block和__weak修饰符的区别:
1.__block不管是ARC还是MRC模式下都可以使用,可以修饰对象,还可以修饰基本数据类型。
2.__weak只能在ARC模式下使用,也只能修饰对象(NSString),不能修饰基本数据类型(int)。
3.__block对象可以在block中被重新赋值,__weak不可以。
2.tableView 滑动卡的问题
主要是因为从缓存中或者是从本地读取图片给UIImage的时候耗费了时间。需要把下面的两句话放到子线程里面:
-
- NSData *imgData = [NSData dataWithContentsOfURL:[NSURL URLWithString:app.icon]]; //得到图像数据
- 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:
2、assign的情况:NSString *newPt = [pt assing];
4、retain使用了引用计数,retain引起引用计数加1, release引起引用计数减1,当引用计数为0时,dealloc函数被调用,内存被回收;
说明属性会被当成读写的,这也是默认属性。设置器和读取器都需要在@implementation中实现。如果使用@synthesize关键字,读取器和设置器都会被解析;
14.nonatomic:
非原子性访问,对属性赋值的时候不加锁,多线程并发访问会提高性能。如果不加此属性,则默认是两个访问方法都为原子型事务访问;
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。这样的好处能有效的防止野指针。
2.不用ARC的话就会看到很多retian。
3.如果你写了@synthesize abc = _abc;的话,系统自动帮你声明了一个_abc的实例变量。
使用assign: 对基础数据类型 (NSInteger)和C数据类型(int, float, double, char,等)
使用copy: 对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.线程与进程的区别和联系?
进程和线程都是由操作系统所体会的程序运行的基本单元,系统利用该基本单元实现系统对应用的并发性。
程和线程的主要差别在于它们是不同的操作系统资源管理方式。进程有独立的地址空间,一个进程崩溃后,在保护模式下不会对其它进程产生影响,而线程只是一个进程中的不同执行路径。线程有自己的堆栈和局部变量,但线程之间没有单独的地址空间,一个线程死掉就等于整个进程死掉,所以多进程的程序要比多线程的程序健壮,但在进程切换时,耗费资源较大,效率要差一些。但对于一些要求同时进行并且又要共享某些变量的并发操作,只能用线程,不能用进程。