iOS 面试总结

1、iPhone4s  iphone5 iphone5s iphone6 iphone6p 适配

答:1、通过分割屏幕  按每个模块的比例 布局

2、使用autolayout布局  建议配合使用VFL


2、缓存方式

1、afnetworking setImageWithURLRequest  以及数据类

2、讲数据模型  coding 归档到本地

3、

(1)可以将数据缓存到本地磁盘。


(2)可以判断一个资源是否已经被缓存。如果已经被缓存,在请求相同的资源,先到本地磁盘搜索。


(3)可以判断文件缓存什么时候过期。这里为了简单起见这里,我们在请求url资源的时候,给每次请求的文件设定一个过期的时间。


(4)可以实现:如果文件已经被缓存,而且没有过期,这将本地的数据返回,否则重新请求url。


(5)可以实现:如果文件下载不成功或者下载没有完成,下次打开程序的时候,移除这些没有成功或者没有下载完成的文件。

4、把数据放到缓存目录   isExistsFile判断文件是否存在   如果存在 就不再去下载  如果不存在就去下载



5、图片缓存 还可以用sdwebimage   SDImageCache


6、BLOCK

如果要在block内修改block外声明的栈变量,那么一定要对该变量加__block标记

block引起了实例与block之间的循环引用(retain-cycle),并且给出解决方案:不直接使用self而先将self赋值给一个临时变量,然后再使用这个临时变量。


但是,大家注意,我们一定要为这个临时变量增加__block标记


7、线程

01. iOS有三种多线程编程的技术,分别是:

Cocoa operation 

优点:不需要关心线程管理,数据同步的事情,可以把精力放在自己需要执行的操作上。

Cocoa operation 相关的类是 NSOperation ,NSOperationQueue。NSOperation是个抽象类,使用它必须用它的子类,可以实现它或者使用它定义好的两个子类:NSInvocationOperation 和 NSBlockOperation。创建NSOperation子类的对象,把对象添加到NSOperationQueue队列里执行。

02.GCD

Grand Central Dispatch (GCD)是Apple开发的一个多核编程的解决方法。在iOS4.0开始之后才能使用。GCD是一个替代诸如NSThread, NSOperationQueue, NSInvocationOperation等技术的很高效和强大的技术。



03.NSThread的使用

 NSThread 有两种直接创建方式:

- (id)initWithTarget:(id)target selector:(SEL)selector object:(id)argument

+ (void)detachNewThreadSelector:(SEL)aSelector toTarget:(id)aTarget withObject:(id)anArgument

第一个是实例方法,第二个是类方法

[cpp] view plaincopy

1、[NSThread detachNewThreadSelector:@selector(doSomething:) toTarget:self withObject:nil];  

2、NSThread* myThread = [[NSThread alloc] initWithTarget:self  

                                        selector:@selector(doSomething:)  

                                        object:nil];  

[myThread start];  

2.2参数的意义:

selector :线程执行的方法,这个selector只能有一个参数,而且不能有返回值。

target  :selector消息发送的对象

argument:传输给target的唯一参数,也可以是nil


用NSObject的类方法  performSelectorInBackground:withObject: 创建一个线程:

[Obj performSelectorInBackground:@selector(doSomething) withObject:nil];


2.4 下载图片的例子:


-(void)downloadImage:(NSString *) url{  

    NSData *data = [[NSData alloc] initWithContentsOfURL:[NSURL URLWithString:url]];  

    UIImage *image = [[UIImage alloc]initWithData:data];  

    if(image == nil){  

          

    }else{  

        [self performSelectorOnMainThread:@selector(updateUI:) withObject:image waitUntilDone:YES];  

    }  

}  

  

-(void)updateUI:(UIImage*) image{  

    self.imageView.image = image;  

}  

  

  

- (void)viewDidLoad  

{  

    [super viewDidLoad];  

      

//    [NSThread detachNewThreadSelector:@selector(downloadImage:) toTarget:self withObject:kURL];  

    NSThread *thread = [[NSThread alloc]initWithTarget:self selector:@selector(downloadImage:) object:kURL];  

    [thread start];  

}  

  

- (void)didReceiveMemoryWarning  

{  

    [super didReceiveMemoryWarning];  

    // Dispose of any resources that can be recreated.  

}  

  

@end  

2.4.2线程间通讯

线程下载完图片后怎么通知主线程更新界面呢?

[self performSelectorOnMainThread:@selector(updateUI:) withObject:image waitUntilDone:YES];

performSelectorOnMainThread是NSObject的方法,除了可以更新主线程的数据外,还可以更新其他线程的比如:

用:performSelector:onThread:withObject:waitUntilDone: 

2、GCD

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{


        dispatch_async(dispatch_get_main_queue(), ^{


        });

});


dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);  

dispatch_group_t group = dispatch_group_create();  

dispatch_group_async(group, queue, ^{  

    [NSThread sleepForTimeInterval:1];  

    NSLog(@"group1");  

});  

dispatch_group_async(group, queue, ^{  

    [NSThread sleepForTimeInterval:2];  

    NSLog(@"group2");  

});  

dispatch_group_async(group, queue, ^{  

    [NSThread sleepForTimeInterval:3];  

    NSLog(@"group3");  

});  

dispatch_group_notify(group, dispatch_get_main_queue(), ^{  

    NSLog(@"updateUi");  

});  

dispatch_release(group);  


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

例子代码如下:

[cpp] view plaincopy

dispatch_queue_t queue = dispatch_queue_create("gcdtest.rongfzh.yc", DISPATCH_QUEUE_CONCURRENT);  

dispatch_async(queue, ^{  

    [NSThread sleepForTimeInterval:2];  

    NSLog(@"dispatch_async1");  

});  

dispatch_async(queue, ^{  

    [NSThread sleepForTimeInterval:4];  

    NSLog(@"dispatch_async2");  

});  

dispatch_barrier_async(queue, ^{  

    NSLog(@"dispatch_barrier_async");  

    [NSThread sleepForTimeInterval:4];  

  

});  

dispatch_async(queue, ^{  

    [NSThread sleepForTimeInterval:1];  

    NSLog(@"dispatch_async3");  

}); 


执行某个代码片段N次。

dispatch_apply(N, globalQ, ^(size_t index) {


});



3、NSOperation


- (void)viewDidLoad  

{  

    [super viewDidLoad];  

    NSInvocationOperation *operation = [[NSInvocationOperation alloc]initWithTarget:self  

                                                                           selector:@selector(downloadImage:)  

                                                                             object:kURL];  

      

    NSOperationQueue *queue = [[NSOperationQueue alloc]init];  

    [queue addOperation:operation];  

    // Do any additional setup after loading the view, typically from a nib.  

}  

  

-(void)downloadImage:(NSString *)url{  

    NSLog(@"url:%@", url);  

    NSURL *nsUrl = [NSURL URLWithString:url];  

    NSData *data = [[NSData alloc]initWithContentsOfURL:nsUrl];  

    UIImage * image = [[UIImage alloc]initWithData:data];  

    [self performSelectorOnMainThread:@selector(updateUI:) withObject:image waitUntilDone:YES];  

}  

-(void)updateUI:(UIImage*) image{  

    self.imageView.image = image;  

}  


如何控制线程池中的线程数

队列里可以加入很多个NSOperation, 可以把NSOperationQueue看作一个线程池,可往线程池中添加操作(NSOperation)到队列中。线程池中的线程可看作消费者,从队列中取走操作,并执行它。

通过下面的代码设置:

[queue setMaxConcurrentOperationCount:5];

线程池中的线程数,也就是并发操作数。默认情况下是-1,-1表示没有限制,这样会同时运行队列中的全部的操作


你可能感兴趣的:(iOS 面试总结)