iOS面试题之人在面试都是套路(一)**颜值APP iOS面试题总结

iOS面试题之人在面试都是套路(一)**颜值APP iOS面试题总结_第1张图片
**颜值APP iOS面试题

人在面试,都是套路!

1.iOS视图控制对象的生命周期(从init开始)

1、 alloc 创建对象,分配空间

2、 init (initWithNibName) 初始化对象,初始化数据

3、 loadView 从nib载入视图 ,除非你没有使用xib文件创建视图

4、 viewDidLoad 载入完成,可以进行自定义数据以及动态创建其他控件

5、 viewWillAppear视图将出现在屏幕之前,马上这个视图就会被展现在屏幕上了

6、 viewDidAppear 视图已在屏幕上渲染完成

7、viewWillDisappear 视图将被从屏幕上移除之前执行

8、viewDidDisappear 视图已经被从屏幕上移除,用户看不到这个视图了

9、dealloc 视图被销毁,此处需要对你在init和viewDidLoad中创建的对象进行释放.

10、viewVillUnload- 当内存过低,即将释放时调用;

11、viewDidUnload-当内存过低,释放一些不需要的视图时调用。

2.UITabView的重用机制的理解,cell的赋值方法?

对于重用机制的理解

  • 屏幕上滑出屏幕时,系统会把这个单元格添加到重用队列中,等待被重用,当有新单元从屏幕外滑入屏幕内时,从重用队列中找看有没有可以重用的单元格,若有,就直接用,没有就重新创建一个。

解决cell重用的问题

  • 如一个TableView中有10个单元格,但屏幕最多显示5个,实际上iPhone只为其分配5个单元格的内存,没有分配10个,当滚动单元格时,屏幕内显示的单元格重复使用这5个内存。实际上分配的Cell的个数为屏幕最大显示数,当有新的Cell进入屏幕时,会随机调用已经滚出屏幕的Cell所占的内存,这就是Cell的重用。

Cell的赋值方法(不太明白问这道题几个意思)

cell.textLabel.text = [NSString stringWithFormat:@"%ld- %ld",indexPath.row,indexPath.section];

附加问题:是调用行高的方法先走还是调用内容的方法先走?

// 设置行高的
  - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath;  
// 设置每行的内容
  - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath; 
  • 当tableView在确定了加载的行数之后,先调用一次设置行高的方法,然后调用设置行内容的方法。(面试时脑子短路(>_<)

3.多线程的几种类型使用,多线程的一般用法?

四种类型如图所示

iOS面试题之人在面试都是套路(一)**颜值APP iOS面试题总结_第2张图片
多线程

多线程一般用法(如果说在网络请求中这天就聊不下去了!!!尽量扯在别处的用法,起码是其他去面试的不说的)

案例1:开发中常见情景,比如发送一条微博动态,用户可以在本地界面编辑好一条微博动态上传服务器,上传后要清除本机暂存档,这条微博包含文本JSON和一张图片,所以上传微博动态的工作就包含上传JSON文件和图片两个内容,并且在用户上传过程中可以随时取消,让用户继续编辑重新上传这个微博动态,这比较适合用NSOperation写。
1.首先我们要写一个NSOperation的子类,要重写掉main中的方法。

.h文件
@interface WeiboUploadOperation : NSOperation
@property (nonatomic, strong) UIImage *image;
@property (nonatomic, strong) NSString *JSON;
@end
.m文件
@implementation 
WeiboUploadOperation
- (void)main
{
    @autoreleasepool {
    // 1. Upload image
    // 2. Upload JSON
    }
}
@end

在main里面,要建立自动释放池autorelease pool。
接下来的问题来了:上传照片和JSON文字时,我们会调用NSURLSession 的相应 API,但是这些API都是非同步的,但是在main中的这些方法里,如果不做特殊的处理,还没收到连续响应,main早就已经执行结束了。我们必须要停在main中,等待API响应。
2.要在operation的中途停下来的时候等待响应,大致有两种思路,一种是在operation当中执行NSRunloop,另外一种就是使用GCD的semaphore
3.在还没有GCD之前,如果希望一个operation可以在某一个地方停下来等候其他的事件发生,做法就是在这条线程中执行Runloop。Runloop就是那个之所以让图形化界面(GUI)的程序一直执行,而不会像某个function或者method从头到尾跑圈就结束的循环(也就是跑圈啦)。在iOS中,除了主线程会执行最主要的Runloop([ NSRunloop mainRunLoop])之外,每个线程也有属于自己的Run loop,只要调用 [NSRunloop currentRunLoop],调用的就是当前线程自己的Runloop,所以要注意,虽然在不同的线程,我们调用的都是[NSRunloop currentRunLoop],但是+currentRunLoop这个类方法回调的并不看做一个类。此外,NSRunloop并不可以手动建立,我们只能使用系统提供的Runloop类。(好像跑偏额(≧▽≦)/啦啦啦)
4.我们要做的是能够在这个operation 执行到一半时喊停,要取消一条operation,那就是要调用 NSOperation的cancel这个方法了,因为我们重写了NSOperation,改变operation里面做的事情,那顺带也重写了cancel,当我们的operation在跑Runloop时候,我们的cancel必须能够通知Runloop停止。当一条线程在跑自己的Runloop之后,如果不同线程之间想要互相通信,那我们就必须在当前的线程建立NSPort类,NSPort介个是个什么东东呢?请移步看苹果爸爸咋说吧。Runloop。将 NSPort 类注册到Runloop内,才可以把消息传到Runloop里面,所以当外部要求Port调用invalidate的时候,就会让Runloop收到消息,停止继续跑,继续执行-main这个方法接下来的方法。
NSPort 也有封装的 Core Foundation 实现,像CFMessagePort等,但是在iOS7之后就没有办法使用了CFMessagePort。iOS7之后之后,调用CFMessagePortCreateLocal或者CFMessagePortCreateRemote这些新建CFMessagePort的函数都无法建立类,只能回传NULL(可以参照CFMessagePort的文档),苹果不允许让我们使用CFMessagePort的原因是:CFMessagePort不但可以传递消息到其他线程的RunLoop上,甚至可以传到其他进程的Runloop上,而iOS 政策上是不允许进程之间相互连通的。
废话说完,上代码

.h文件
@interface WeiboUploadOperation : NSOperation
{
    NSPort *port;
    BOOL runloopRunning;
}
@property (nonatomic, strong) UIImage *image;
@property (nonatomic, strong) NSString *JSON;
@end
.m文件
@implementation 
WeiboUploadOperation
- (void)main
{
    “@autoreleasepool {
        [someAPI uploadImageData:UIImagePNGRepresentation(self.image) callback:^ {
            [self quitRunLoop];
        }];
        [self doRunloop];
        if (self.isCancelled) {
            return;
        }
    [someAPI uploadJSON:self.JSON callback:^ {
            [self quitRunLoop];
        }];
        [self doRunloop];
    }
}
- (void)doRunloop
{
    runloopRunning = YES;
    port = [[NSPort alloc] init];
    [[NSRunLoop currentRunLoop] addPort:port forMode:NSRunLoopCommonModes];
    while (runloopRunning && !self.isCancelled) {
        @autoreleasepool {
            [[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.5]];
        }
    }
    port = nil;
}

- (void)quitRunLoop
{
    [port invalidate];
    runloopRunning = NO;
}

- (void)cancel
{
    [super cancel];
    [self quitRunLoop];
}
@end
*注意:伪代码而已,说明思路,someAPI就是指自己程序里的自己封装网络请求
此外呢,其实还有一种方法啦,只是不常用-GCD Semaphores

有了GCD之后呢,很多事情就变得很简单了,当我们想要执行到一半的时候暂停下来,现在可以选择建立semaphore。接下来:

  • 只要对semaphore调用dispatch_semaphore_wait,程序就会在该暂停的的地方暂停等候。
  • 对于已经在等候中的semaphore,再调用dispatch_semaphore_signal,发送signal,程序就会往下面继续执行。
    上代码
.h文件
@interface WeiboUploadOperation : NSOperation
@property (nonatomic, strong) UIImage *image;
@property (nonatomic, strong) NSString *JSON;
@property (nonatomic, strong) dispatch_semaphore_t semaphore;
@end
.m文件
@implementation 
WeiboUploadOperation
 - (void)main
{
    @autoreleasepool {
        self.semaphore = dispatch_semaphore_create(0);
        [someAPI uploadImageData:UIImagePNGRepresentation(self.image) callback:^{
        dispatch_semaphore_signal(self.semaphore);
        }];
        dispatch_semaphore_wait(self.semaphore, DISPATCH_TIME_FOREVER);
        if (self.cancelled) {
            return;
        }
        self.semaphore = dispatch_semaphore_create(0);
        [someAPI uploadJSON:self.JSON callback:^
        {
        dispatch_semaphore_signal(self.semaphore);
        }];
        dispatch_semaphore_wait(self.semaphore, DISPATCH_TIME_FOREVER);
    }
}

 - (void)cancel
{
    [super cancel];
   dispatch_semaphore_signal(self.semaphore);
}
@end
*someAPI指的是请求网络的代码,很多种写法啦

4.如何优化页面的加载效率?

我表示丈二的和尚摸不到头脑,给我留那么点空,够写吗?
发现一篇文章不错:如何让iOS 保持界面流畅?这些技巧你知道吗?
好吧,我没那么牛逼,我当时只写的TableView的优化:

TableView表格性能优化
  • 行高一定要缓存!!!
  • 不要动态创建子视图,所有的子视图都预先创建,如果不需要显示可以设置为hidden
  • 所有的子视图都应该添加到contentview上
  • 所有的子视图必须指定背景颜色
  • 所有的颜色都不要使用alpha
  • cell栅格化
  • 异步绘制
//将 cell 的图层内容生成一张图像并且缓存,在滚动中,不再生成 cell 的内容
self.layer.shouldRasterize = true // 一定要设置分辨率
self.layer.rasterizationScale = UIScreen.mainScreen().scale
//异步绘制
cell.layer.drawsAsynchronously = true

5.代理和block的区别?

服,不服不行,应聘的也不是初级岗,还问
详细文章写得比我好的多得是,请移步
谈Objective-C block的实现
我当时就简单写得

  • 代理(delegate):约定好的协议,调用方法实现协议的方法,接受在需要的时候,通知delegate执行这个方法。
  • block:是提前准备好的代码,传递给接收方,至于什么时候被执行,调用方并不知道。

6.UIImagePickerController和AVCaptureSession对比?

我表示并不知道,当时没写空着。
网上的资料也都好老,先空着这,以后更新

7.内存过高和CPU负载过高引起的原因和解决办法?

这是个永久的命题啊!!!!!
iOS 界面构建中的各种性能问题以及对应的解决思路

8.不同尺寸的iphone应用的适配都有几种办法,优缺点?

我表示就用过三种
-** AutoLayout**
直接建立约束条

[self.view addConstraint:[NSLayoutConstraint constraintWithItem:blueView                   attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:redView attribute:NSLayoutAttributeLeft multiplier:1 constant:0]];

VFL

 - (void)viewDidLoad { 
[super viewDidLoad];
 UIButton *button=[[UIButton alloc]init];
 [button setTitle:@"点击一下" forState:UIControlStateNormal]; button.translatesAutoresizingMaskIntoConstraints=NO;
 [button setBackgroundColor:[UIColor blackColor]];
 [self.view addSubview:button]; 
NSArray *constraints1=[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-[button]-|" 
                                   options:0
                                   metrics:nil    
                                   views:NSDictionaryOfVariableBindings(button)]; 
NSArray *constraints2=[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-20-[button(==30)]"
                                  options:0 
                                  metrics:nil 
                                  views:NSDictionaryOfVariableBindings(button)]; 
[self.view addConstraints:constraints1]; 
[self.view addConstraints:constraints2]; 
}

这是一种痛苦的写法,但是比三方库要靠谱,也不会出现问题。

  • Masonry
    详细用法请移步Masonry github地址
  • SDAutoLayout
    详细用法请移步SDAutoLayout github地址
    -Apple设备尺寸和编程尺寸
iOS面试题之人在面试都是套路(一)**颜值APP iOS面试题总结_第3张图片
iPhone设备

以下是面试问的问题(回忆一下也是醉了,绝对的大牛啊,我就是当时知道答案,也会被问蒙蔽的)

1 项目中加锁的场景以及加锁的用法?

我还是太菜,还是看别人的文章吧
深入理解 iOS 开发中的锁 作者 bestswifter

笔试题套路不深,主要是面试啊,未完待续,下篇继续。。。。。

你可能感兴趣的:(iOS面试题之人在面试都是套路(一)**颜值APP iOS面试题总结)