美文网首页iOS面试题iOS开发iOS面试题
iOS面试题之人在面试都是套路(一)**颜值APP iOS面试题

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

作者: Miu七七 | 来源:发表于2016-10-27 15:05 被阅读879次
    **颜值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.多线程的几种类型使用,多线程的一般用法?

    四种类型如图所示

    多线程

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

    案例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这个方法接下来的方法。<br />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]; 
    }
    

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

    iPhone设备

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

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

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

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

    相关文章

      网友评论

        本文标题:iOS面试题之人在面试都是套路(一)**颜值APP iOS面试题

        本文链接:https://www.haomeiwen.com/subject/wbdjuttx.html