当前位置:文档之家› iOS工程师面试题

iOS工程师面试题

1.谈谈你对多线程开发的理解?iOS中有几种实现多线程的方法?
好处:1、使用线程可以把程序中占据时间长的任务放到后台去处理,如图片、视频的下载2、发挥多核处理器的优势,并发执行让系统运行的更快、更流畅,用户体验更好缺点:1、大量的线程降低代码的可读性,2、更多的线程需要更多的内存空间3、当多个线程对同一个资源出现争夺的时候要注意线程安全的问题。

iOS有三种多线程编程的技术:1、NSThread(两种创建方式)[NSThread detachNewThreadSelector:@selector(doSomething:)toTarget:self withObject:nil];NSThread *myThread = [[NSThread alloc] initWithTarget:self selector:@selector(doSomething:) object:nil];[myThread start];2、NSOperationQueueNSOperationQueue *oprationQueue = [[NSOperationQueue alloc] init];oprationQueue addOperationWithBlock:^{//这个block语句块在子线程中执行}/?p=2373、dispatch_async(dispatch_get_global_queue(DISPATCH_QUEU E_PRIORITY_DEFAULT, 0), ^{// 耗时的操作dispatch_async(dispatch_get_main_queue(), ^{// 更新界面});});/article/details/8016129PS:不显示的创建线程的方法:用NSObject的类方法performSelectorInBackground:withObject: 创建一个线程:[Obj performSelectorInBackground:@selector(doSomething)withObject:nil];1.线程同步和异步的区别?IOS中如何实现多线程的同步?
同步:一个线程要等待上一个线程执行完之后才能执行当前的线程,生活中的例子(上厕所)。

异步:同时去做两件或者多件事。

比如边听歌边看报。

原子操作(atomic)、加锁(NSLock、NSRecursive、NSConditionLock)、@synchronized GCD串行队列,GCD当中的屏障,NSOperationQueue设置最大并发数为1参考(/article/details/7487505)1.iOS类是否可以多继承?如果没有,那可以用其他方法实现吗?简述实现过程。


不可以,可以通过消息转发、delegate和protocol和类别来实现类似多继承。

1.iOS本地数据存储都有哪几种方式?iOS如何实现复杂对象的存储?NSKeyedArchiver(归档)采用归档的形式来保存数据,该数据对象需要遵守NSCoding协议,并且该对象对应的类必须提供encodeWithCoder:和initWithCoder:方法。

1.NSUserDefaults:用来保存应用程序设置和属性、用户保存的数据。

用户再次打开程序或开机后这些数据仍然存在。

NSUserDefaults可以存储的数据类型包括:NSData、NSString、NSNumber、NSDate、NSArray、NSDictionary。

2.Write写入方式:永久保存在磁盘中。

3.SQLite(FMDB、CoreData)NSCoding + NSKeyedArchiver实现复杂对象的存储。

1.深拷贝和浅拷贝的理解?深拷贝拷贝的是内容,浅拷贝拷贝的是指针。

深拷贝和浅拷贝最大的区别就是子类对象的地址是否改变,如果子类对象的地址改变那么就是深拷贝。

1.怎样实现一个singleton的类。

static LOSingleton * shareInstance;+( LOSingleton *)sharedInstance{@synchronized(self){//这个东西其实就是一个加锁。

如果self 其他线程访问,则会阻塞。

这样做一般是用来对单例进行一个死锁的保护if (shareInstance == nil) {shareInstance = [[super allocWithZone:NULL] init];}}return shareInstance;}//第二种方式+ (LOSingleton *) sharedInstance{static LOSingleton *sharedInstance = nil ;static dispatch_once_t onceToken; // 锁dispatch_once (& onceToken, ^ { // 最多调用一次sharedInstance = [[self alloc] init];});return sharedInstance;}1.什么是安全释放?在对象release之后把指针置为nil1.RunLoop是什么?
一个RunLoop就是一个时间处理的循环,用来不停的调度工作以及处理输入时间。

使用runloop的目的是让你的线程在有工作的时候忙于工作,而没工作的时候处于休眠状态。

runloop的设计是为了减少cpu 无谓的空转。

1.什么是序列化和反序列化,可以用来做什么?如何在OC中实现复杂对象的存储?
如果你需要存储一个复杂的对象的话,经常要以二进制的方法序列化这个对象,这个过程叫Archiving。

如果一个对象需要进行序列化,那么需要遵循NScoding协议,主要有两个方法:-(id)initWithCoder:(NSCoder*)coder;//从coder中读取数据,保存到相应变量中,即反序列化数据。

-(void)encodeWithCoder:(NSCoder*)coder;//读取实例变量,并把这些数据写到coder中去,即序列化数据。

1.简述应用程序按Home键进入后台时的生命周期,以及从后台回到前台时的生命周期?
应用程序的状态:
Not running 未运行,程序没启动
Inactive 未激活,程序在前台运行,不过没接受到事件,没有事件处理的状态下通常处于这个状态。

Active 激活程序在前台并且接收到了事件Backgound后台程序在后台而且能执行代码,大多数程序进入这个状态后会在在这个状态上停留一会。

Suspended 挂起程序在后台不能执行代码。

- (BOOL)application:(UIApplication *)application willFinishLaunchingWithOptions:(NSDictionary *)launchOptions //告诉代理进程启动但还没进入状态保存- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions//告诉代理启动基本完成程序准备开始运行- (void)applicationWillResignActive:(UIApplication *)application//当应用程序将要入非活动状态执行,在此期间,应用程序不接收消息或事件,比如来电话了- (void)applicationDidBecomeActive:(UIApplication *)application// 当应用程序入活动状态执行,这个刚好跟上面那个方法相反- (void)applicationDidEnterBackground:(UIApplication *)application//当程序被推送到后台的时候调用。

所以要设置后台继续运行,则在这个函数里面设置即可- (void)applicationWillEnterForeground:(UIApplication *)application//当程序从后台将要重新回到前台时候调用,这个刚好跟上面的那个方法相反。

- (void)applicationWillTerminate:(UIApplication *)application//当程序将要退出是被调用,通常是用来保存数据和一些退出前的清理工作。

这个需要要设置UIApplicationExitsOnSuspend的键值。

- (void)applicationDidFinishLaunching:(UIApplication*)applicatio//当程序载入后执行1.描述应用程序的启动顺序。

1、程序入口main函数创建UIApplication实例和UIApplication代理实例2、在UIApplication代理实例中重写启动方法,设置第一ViewController3、在第一ViewController中添加控件,实现对应的程序界面。

1.UIImage初始化一张图片有几种方法?简述各自的优缺点。


1、从资源读取UIImage *image = [UIImage imageNamed:@”1.png”];2、从网络读取NSURL*url=[NSURL URLWithString:@"/photo_auto/chezhan/2012/50/00/15/80046_950.jpg"];3.从手机本地读取//读取本地图片非resourceNSString*aPath3=[NSString stringWithFormat:@"%@/D ocuments/%@.jpg",NSHomeDirectory(),@"test"];UIImage*imgFr omUrl3=[[UIImage alloc]initWithContentsOfFile:aPath3];4.从现有的context中获得图像//add ImageIO.framework and #import <ImageIO/ImageIO.h>CGImageSourceRef source = CGImageSourceCreateWithURL((CFURLRef)url, NULL);CGImageRef img= CGImageSourceCreateImageAtIndex(source,0,NULL);CGContextRef ctx=UIGraphicsGetCurrentContext();CGContextSaveGState(ctx);//transformCTM的2种方式//CGContextConcatCTM(ctx, CGAffineTransformMakeScale(.2, -0.2));//CGContextScaleCTM(ctx,1,-1);//注意坐标要反下,用ctx来作为图片源CGImageRef capture=CGBitmapContextCreateImage(ctx);CGContextDrawImage(ctx, CGRectMake(160, 0, 160, 230), [image CGImage]);CGContextDrawImage(ctx, CGRectMake(160, 230, 160, 230), img);CGImageRef capture2=CGBitmapContextCreateImage(ctx);5、用Quartz的CGImageSourceRef来读取图片CGImageSourceRef source = CGImageSourceCreateWithURL((CFURLRef)url, NULL);CGImageRef img= CGImageSourceCreateImageAtIndex(source,0,NULL);参考(/article/details/7526147#)1.这段代码有什么问题吗:@implementation Person- (void)setAge:(int)newAge {self.age = newAge;}@end死循环1.这段代码有什么问题,如何修改for (int i = 0; i < someLargeNumber; i++) {NSString *string = @”Abc”;string = [string lowercaseString];string = [string stringByAppendingString:@"xyz"];NSLog(@“%@”, string);}如果数字很大的话会造成内存一直增加(因为一直通过便利构造器方法创建autorelease对象),直到循环结束才减少,在循环内加一个自动释放池,更改后代码如下:for (int i = 0; i < someLargeNumber; i++) {NSString *string = @”Abc”;@autoreleasepool {string = [string lowercaseString];string = [string stringByAppendingString:@"xyz"];NSLog(@“%@”, string);}}1.截取字符串”20 | ”中,”|”字符前面和后面的数据,分别输出它们。

相关主题