iOS笔试面试iOS FoundationsiOS面试题

可能碰到的iOS笔试面试题(10)--UI

2016-05-04  本文已影响1847人  b485c88ab697

UI

viewcontroller的一些方法的说明viewDidLoad,viewWillDisappear, viewWillAppear方法的 顺序和作用?

viewWillAppear:视图即将可见时调用。默认情况下不执行任何操作

viewDidAppear:视图已完全过渡到屏幕上时调用

viewWillDisappear:视图被驳回时调用,覆盖或以其他方式隐藏。默认情况下不执行任何操作

viewDidDisappear:视图被驳回后调用,覆盖或以其他方式隐藏。默认情况下不执行任何操作loadView; .这是当他们没有正在使用nib视图页面,子类将会创建自己的自定义视图层。绝不能直接调用。

viewDidLoad:在视图加载后被调用,如果是在代码中创建的视图加载器,他将会在loadView方法后被调用,如果是从nib视图页面输出,他将会在视图设置好后后被调用。

「initWithNibName: bundle:」载入nib档案来初始化「loadView」载入视图「viewDidLoad」在载入视图至内存后会呼叫的方法「viewDidUnload」在视图从内存中释放后会呼叫的方法 (当内存过低,释放一些不需要的视图时调用)

「viewWillAppear」当收到视图在视窗将可见时的通知会呼叫的方法

「viewDidAppear」当收到视图在视窗已可见时的通知会呼叫的方法

「viewWillDisappear」当收到视图将去除、被覆盖或隐藏于视窗时的通知会呼叫的方法

「viewDidDisappear」当收到视图已去除、被覆盖或隐藏于视窗时的通知会呼叫的方法

「didReceiveMemoryWarning」收到系统传来的内存警告通知后会执行的方法

「shouldAutorotateToInterfaceOrientation」是否支持不同方向的旋转视图

「willAnimateRotationToInterfaceOrientation」在进行旋转视图前的会执行的方法(用于调整旋转视图之用)

代码的执行顺序

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

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

3、loadView 从nib载入视图 ,通常这一步不需要去干涉。除非你没有使用xib文件创建视图

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

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

6、viewDidAppear 视图已在屏幕上渲染完成当一个视图被移除屏幕并且销毁的时候的执行顺序,这个顺序差不多和上面的相反

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

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

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

什么是key window?

谈一谈你是怎么封装view的

- 先添加所需子控件
- 再接收模型数据根据模型数据设置子控件数据和位置
- 简而言之, 自己的事情自己做, 把不需要暴露出去的封装起来

简单说一下APP的启动过程,从main文件开始说起

    程序启动分为两类:1.有storyboard 2.没有storyboard
有storyboard情况下:
1.main函数
2.UIApplicationMain
* 创建UIApplication对象
* 创建UIApplication的delegate对象
3.根据Info.plist获得Main.storyboard的文件名,加载Main.storyboard(有storyboard)
* 创建UIWindow
* 创建和设置UIWindow的rootViewController
* 显示窗口

没有storyboard情况下:
1.main函数
2.UIApplicationMain
* 创建UIApplication对象
* 创建UIApplication的delegate对象
3.delegate对象开始处理(监听)系统事件(没有storyboard)
* 程序启动完毕的时候, 就会调用代理的application:didFinishLaunchingWithOptions:方法
* 在application:didFinishLaunchingWithOptions:中创建UIWindow
* 创建和设置UIWindow的rootViewController
* 显示窗口

怎么解决缓存池满的问题(cell)

iOS中不存在缓存池满的情况,因为通常我们ios中开发,对象都是在需要的时候才会创建,有种常用的说话叫做懒加载,还有在UITableView中一般只会创建刚开始出现在屏幕中的cell,之后都是从缓存池里取,不会在创建新对象。缓存池里最多也就一两个对象,缓存池满的这种情况一般在开发java中比较常见,java中一般把最近最少使用的对象先释放。

UIButton与UITableView的层级结构

设置scroll view的contensize能在Viewdidload里设置么,为什么

简述你对UIView、UIWindow和CALayer的理解

frame和bounds有什么不同?(Difference between frame and bounds?)

关于页面间传值的问题?

属性传值:A页面设置属性 NSString *paramString,在跳转B页面的时候初始化paramString。
//A页面.h文件
@property (nonatomic, copy)NSString *paramString;
//A页面.m文件
 NextViewController *nextVC = [[NextViewController alloc] init];
 nextVC.paramString = @"参数传质";
 [self presentViewController:nextVC animated:YES completion:nil];
 
委托delegate传值:在B页面定义delegate,并且设置delegate属性,在A页面实现delegate协议

通知notification传值:在B页面中发送通知,在A页面注册观察者并且在不用的时候移除观察者。
//B页面发送通知 
[[NSNotificationCenter defaultCenter] postNotificationName:@"ChangeNameNotification" object:self userInfo:@{@"name":self.nameTextField.text}];
 [self dismissViewControllerAnimated:YES completion:nil]; 
//A页面注册观察者
 [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(ChangeNameNotification:) name:@"ChangeNameNotification" object:nil];
}
//观察到通知时候的处理方法
-(void)ChangeNameNotification:(NSNotification*)notification{
    NSDictionary *nameDictionary = [notification userInfo];
    self.nameLabel.text = [nameDictionary objectForKey:@"name"];
}
//通知不使用的时候移除观察者
 [[NSNotificationCenter defaultCenter] removeObserver:self];


block传值:在B页面定义一个block类型的变量,在B页面跳转A的时候调用这个block。在A页面跳转到B页面的时候对B页面的block赋值。
//B页面定义block,并设置block类型的变量
 typedef void (^ablock)(NSString *str);
 @property (nonatomic, copy) ablock block; 
//B页面跳转到A页面调用这个block
 self.block(self.nameTextField.text);
 [self dismissViewControllerAnimated:YES completion:nil];
//A页面跳转到B页面的时候对B页面的block赋值,这样在B页面跳转的时候就会回调这个block函数
 [self presentViewController:second animated:YES completion:nil];
 second.block = ^(NSString *str){
        self.nameLabel.text = str;
    }; 
 
 kvo传值:在A页面设置B页面的变量second,并且对这个变量进行观察
- (void)addObserver:(NSObject * _Nonnull)anObserver forKeyPath:(NSString * _Nonnull)keyPath options:(NSKeyValueObservingOptions)options context:(void * _Nullable)context
并在A页面实现
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *,id> *)change context:(void *)context方法。
在B页面对变量keyPath进行设置,在A页面都会观察的到。
@property (nonatomic, strong) SecondViewController *second; 
//在A视图跳转到B视图的地方添加如下代码 
self.second = [[SecondViewController alloc] initWithNibName:@"SecondViewController" bundle:nil];
[self.second addObserver:self forKeyPath:@"userName" options:NSKeyValueObservingOptionNew context:nil];
[self presentViewController:self.second animated:YES completion:nil];
//实现这个观察对象的方法
 -(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context 
//在B页面对userName进行设置,在A页面都可以间听到
 
 单例模式传值:通过全局的方式保存
 对于通知代理面试常问, 代理和通知分别在什么情况下使用? 区别? 各自优点?

关于视图的生命周期的问题

响应者链条? (What is responder chain?)

如果当前view不能处理当前事件,那么事件将会沿着响应者链(Responder Chain)进行传递,知道遇到能处理该事件的响应者(Responsder Object)。 imageimage
- 接收事件的initial view如果不能处理该事件并且她不是顶层的View,则事件会往它的父View进行传递。

- initial view的父View获取事件后如果仍不能处理,则继续往上传递,循环这个过程。如果顶层的View还是不能处理这个事件的话,则会将事件传递给它们的ViewController,

- 如果ViewController也不能处理,则传递给Window(UIWindow),此时Window不能处理的话就将事件传递UIApplication,最后如果连Application也不能处理,则废弃该事件

ViewController的loadView,viewDidLoad,viewDidUnload分别是在什么时候调用的?在自定义ViewController的时候这几个函数里面应该做什么工作?

UITableView的重用机制?(或者如何在一个view上显示多个tableView,tableView要求不同的数据源以及不同的样式 (要求自定义cell), 如何组织各个tableView的delegate和dataSource?请说说实现思路?)

在一个tableView中需要自定义多种样式的cell(两种或三种),通常你如何实现,说说思路即可?

UITableView的性能优化? 滑动的时候有种卡的感觉是为什么?怎么解决?

tableview的cell里如何嵌套collection view?

思路同网易新闻类似,用自定义的继承自UITableViewCell的类,在initWithFrame的构造方法中, 初始化自定义的继承自UICollectionView的类

下拉和上拉的原理?

如何实现cell的动态的行高?

谈谈webView

awakeFromNib与viewdidload区别

layoutSubview何时调用?

viewcontroller的didreceivememorywaring在什么时候调用 默认操作是什么

UIWindow和UIView和 CALayer 的联系和区别?

UIScrollView

如何实现瀑布流,流水布局

UIImage有哪几种加载方式

描述九宫格算法

实现图片轮播图

应用的生命周期

load initialize方法的区别

UIScrollView 大概是如何实现的,它是如何捕捉、响应手势的?

// 让UIScrollView遵守UIGestureRecognizerDelegate协议,实现这个方法,在这里方法里对添加的手势进行处理就可以解决冲突

+[UIView animateWithDuration:animations:completion:] 内部大概是如何实现的?

animateWithDuration:这就等于创建一个定时器
animations:这是创建定时器需要实现的SEL
completion:是定时器结束以后的一个回调block

什么时候会发生「隐式动画」?

如何把一张大图缩小为1/4大小的缩略图?

imgData = UIImageJPEGRepresentation(image, 0.6f)

当TableView的Cell改变时,如何让这些改变以动画的形式呈现?

[tableView deselectRowAtIndexPath:indexPath animated:TRUE];
// 重点是这2句代码实现的功能
[tableView beginUpdates];
[tableView endUpdates];

为什么当 Core Animation 完成时,layer 又会恢复到原先的状态?

设计一个进度条。

  1. 自定义一个UIView的子类

     //提供一个成员属性,接收下载进度值
     @property (nonatomic, assign) CGFloat progress;
    
  2. 重写成员属性progress的setter

     //每次改变成员属性progress的值,就会调用它的setter
     -(void)setProgress:(CGFloat)progress
     {
     _progress = progress;
     //当下载进度改变时,手动调用重绘方法
     [self setNeedsDisplay];
     }
    
  3. 重写

     -(void)drawRect:(CGRect)rect(核心)
     -(void)drawRect:(CGRect)rect
     {
     //设置圆弧的半径
     CGFloat radius = rect.size.width * 0.5;
     //设置圆弧的圆心
     CGPoint center = CGPointMake(radius, radius);
     //设置圆弧的开始的角度(弧度制)
     CGFloat startAngle = - M_PI_2;
     //设置圆弧的终止角度
     CGFloat endAngle = - M_PI_2 + 2 * M_PI * self.progress;
     //使用UIBezierPath类绘制圆弧
     UIBezierPath *path = [UIBezierPath bezierPathWithArcCenter:center radius:radius - 5 startAngle:startAngle endAngle:endAngle clockwise:YES];
     //将绘制的圆弧渲染到图层上(即显示出来)
     [path stroke];
     }
    

如何播放 GIF 图片,有什么优化方案么?

有哪几种方式可以对图片进行缩放,使用 CoreGraphics 缩放时有什么注意事项?

XIB与Storyboards的优缺点?

- XIB:在编译前就提供了可视化界面,可以直接拖控件,也可以直接给控件添加约束,更直观一些,而且类文件中就少了创建控件的代码,确实简化不少,通常每个XIB对应一个类。

- Storyboard:在编译前提供了可视化界面,可拖控件,可加约束,在开发时比较直观,而且一个storyboard可以有很多的界面,每个界面对应一个类文件,通过storybard,可以直观地看出整个App的结构。

- XIB:需求变动时,需要修改XIB很大,有时候甚至需要重新添加约束,导致开发周期变长。XIB载入相比纯代码自然要慢一些。对于比较复杂逻辑控制不同状态下显示不同内容时,使用XIB是比较困难的。当多人团队或者多团队开发时,如果XIB文件被发动,极易导致冲突,而且解决冲突相对要困难很多。

- Storyboard:需求变动时,需要修改storyboard上对应的界面的约束,与XIB一样可能要重新添加约束,或者添加约束会造成大量的冲突,尤其是多团队开发。对于复杂逻辑控制不同显示内容时,比较困难。当多人团队或者多团队开发时,大家会同时修改一个storyboard,导致大量冲突,解决起来相当困难。

控制器View的加载过程?

当程序访问了控制器的View属性时会先判断控制器的View是否存在,如果存在就直接返回已经存在的View;
如果不存在,就会先调用loadView这个方法;如果控制器的loadView方法实现了,就会按照loadView方法加载自定义的View;
如果控制器的loadView方法没有实现就会判断storyboard是否存在;
如果storyboard存在就会按照storyboard加载控制器的View;如果storyboard不存在,就会创建一个空视图返回。

应用程序的启动流程?

1.执行Main
2.执行UIApplicationMain函数.
3.创建UIApplication对象,并设置UIApplicationMain对象的代理.
  UIApplication的第三个参数就是UIApplication的名称,如果指定为nil,它会默认为UIApplication.
  UIApplication的第四个参数为UIApplication的代理.
4.开启一个主运行循环.保证应用程序不退出.
5.加载info.plist.加载配置文件.判断一下info.plist文件当中有没有Main storyboard file base name里面有没有指定storyboard文件,如果有就去加载info.plist文件,如果没有,那么应用程序加载完毕.

事件传递与响应的完整过程?

在产生一个事件时,系统会将该事件加入到一个由UIApplication管理的事件队列中,
UIApplication会从事件队列中取出最前面的事件,将它传递给先发送事件给应用程序的主窗口.
主窗口会调用hitTest方法寻找最适合的视图控件,找到后就会调用视图控件的touches方法来做具体的事情.
当调用touches方法,它的默认做法, 就会将事件顺着响应者链条往上传递,
传递给上一个响应者,接着就会调用上一个响应者的touches方法

下列回调机制的理解不正确的是

A target-action:当两个对象之间有⽐较紧密的关系时,如视图控制器与其下的某个视图。       
B delegate:当某个对象收到多个事件,并要求同一个对象来处理所有事件时。委托机制必须依赖于某个协议定义的⽅法来发送消息。       
C NSNotification:当需要多个对象或两个无关对象处理同一个事件时。       
D Block:适⽤于回调只发⽣生一次的简单任务。
参考答案:B

给UIImageView添加圆角

imgView.layer.cornerRadius = 10;
// 这一行代码是很消耗性能的
imgView.clipsToBounds = YES;
- (UIImage *)hyb_imageWithCornerRadius:(CGFloat)radius {
  CGRect rect = (CGRect){0.f, 0.f, self.size};
  
  UIGraphicsBeginImageContextWithOptions(self.size, NO, UIScreen.mainScreen.scale);
  CGContextAddPath(UIGraphicsGetCurrentContext(),
                   [UIBezierPath bezierPathWithRoundedRect:rect cornerRadius:radius].CGPath);
  CGContextClip(UIGraphicsGetCurrentContext());
  
  [self drawInRect:rect];
  UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
  
  UIGraphicsEndImageContext();
  
  return image;
}

然后调用时就直接传一个圆角来处理:

imgView.image = [[UIImage imageNamed:@"test"] hyb_imageWithCornerRadius:4];

这么做就是on-screen-rendering了,通过模拟器->debug->Color Off-screen-rendering看到没有离屏渲染了!(黄色的小圆角没有显示了,说明这个不是离屏渲染了)

- (void)drawRect:(CGRect)rect {
  CGRect bounds = self.bounds;
  [[UIBezierPath bezierPathWithRoundedRect:rect cornerRadius:8.0] addClip];
 
  [self.image drawInRect:bounds];
}

一个view已经初始化完毕,view上面添加了n个button(可能使用循环创建),除用view的tag之外,还可以采用什么办法来找到自己想要的button来修改Button的值

这个问题有很多种方式,而且不同的使用场景也不一样的。比如说:
•   第一种:如果是点击某个按钮后,才会刷新它的值,其它不用修改,那么不用引用任何按钮,直接在回调时,就已经将接收响应的按钮给传过来了,直接通过它修改即可。
•   第二种:点击某个按钮后,所有与之同类型的按钮都要修改值,那么可以通过在创建按钮时将按钮存入到数组中,在需要的时候遍历查找。

使用drawRect有什么影响?

viewWillLayoutSubView你总是知道的。

controller layout触发的时候,开发者有机会去重新layout自己的各个subview。
横竖屏切换的时候,系统会响应一些函数,其中 viewWillLayoutSubviews 和 viewDidLayoutSubviews。
- (void)viewWillLayoutSubviews  {       
[self _shouldRotateToOrientation:(UIDeviceOrientation)[UIApplication sharedApplication].statusBarOrientation];  
} 
 -(void)_shouldRotateToOrientation:(UIDeviceOrientation)orientation {         

 if (orientation == UIDeviceOrientationPortrait ||orientation ==                 UIDeviceOrientationPortraitUpsideDown)

  {           // 竖屏 } 

 else {          // 横屏     } }
通过上述一个函数就知道横竖屏切换的接口了。 
注意:viewWillLayoutSubviews只能用在ViewController里面,在view里面没有响应。

一个tableView是否可以关联两个不同的数据源?

如何自动计算cell的高度?

UITableView是如何计算内容高度的?为什么初始化时配置数据时,获取行高的代理方法会调用数据条数次?

一个tableView是否可以关联两个不同的数据源?你会怎么处理?

答:首先我们从代码来看,数据源如何关联上的,其实是在数据源关联的代理方法里实现的。
因此我们并不关心如何去关联他,他怎么关联上,方法只是让我返回根据自己的需要去设置如相关的数据源。
因此,我觉得可以设置多个数据源啊,但是有个问题是,你这是想干嘛呢?想让列表如何显示,不同的数据源分区块显示?

给出委托方法的实例,并且说出UITableVIew的Data Source方法

CocoaTouch框架中用到了大量委托,其中UITableViewDelegate就是委托机制的典型应用,是一个典型的使用委托来实现适配器模式,其中UITableViewDelegate协议是目标,tableview是适配器,实现UITableViewDelegate协议,并将自身设置为talbeview的delegate的对象,是被适配器,一般情况下该对象是UITableViewController。
UITableVIew的Data Source方法有- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section;
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath;

cocoa touch框架

答:iPhone OS 应用程序的基础 Cocoa Touch 框架重用了许多 Mac 系统的成熟模式,但是它更多地专注于触摸的接口和优化。

UIKit 为您提供了在 iPhone OS 上实现图形,事件驱动程序的基本工具,其建立在和 Mac OS X 中一样的 Foundation 框架上,包括文件处理,网络,字符串操作等。

Cocoa Touch 具有和 iPhone 用户接口一致的特殊设计。有了 UIKit,您可以使用 iPhone OS 上的独特的图形接口控件,按钮,以及全屏视图的功能,您还可以使用加速仪和多点触摸手势来控制您的应用。

各色俱全的框架 除了UIKit 外,Cocoa Touch 包含了创建世界一流 iPhone 应用程序需要的所有框架,从三维图形,到专业音效,甚至提供设备访问 API 以控制摄像头,或通过 GPS 获知当前位置。

Cocoa Touch 既包含只需要几行代码就可以完成全部任务的强大的 Objective-C 框架,也在需要时提供基础的 C 语言 API 来直接访问系统。这些框架包括:

Core Animation:通过 Core Animation,您就可以通过一个基于组合独立图层的简单的编程模型来创建丰富的用户体验。

Core Audio:Core Audio 是播放,处理和录制音频的专业技术,能够轻松为您的应用程序添加强大的音频功能。

Core Data:提供了一个面向对象的数据管理解决方案,它易于使用和理解,甚至可处理任何应用或大或小的数据模型。

功能列表:框架分类

下面是 Cocoa Touch 中一小部分可用的框架:

音频和视频:Core Audio ,OpenAL ,Media Library ,AV Foundation

数据管理 :Core Data ,SQLite

图形和动画 :Core Animation ,OpenGL ES ,Quartz 2D

网络:Bonjour ,WebKit ,BSD Sockets

用户应用:Address Book ,Core Location ,Map Kit ,Store Kit

xib文件的构成分为哪3个图标?都具有什么功能。

File’s Owner 是所有 nib 文件中的每个图标,它表示从磁盘加载 nib 文件的对象;

First Responder 就是用户当前正在与之交互的对象;

View 显示用户界面;完成用户交互;是 UIView 类或其子类。

简述应用程序按Home键进入后台时的生命周期,和从后台回到前台时的生命周期? 应用程序:

-[AppDelegate application:willFinishLaunchingWithOptions:]
-[AppDelegate application:didFinishLaunchingWithOptions:]
-[AppDelegate applicationDidBecomeActive:] 

退到后台:

-[AppDelegate applicationWillResignActive:] 
-[AppDelegate applicationDidEnterBackground:] 

回到前台:

-[AppDelegate applicationWillEnterForeground:] 
-[AppDelegate applicationDidBecomeActive:] 

ViewController之间,
加载页面:

-[mainViewController viewDidLoad] -[mainViewController viewWillAppear:] -[mainViewController viewWillLayoutSubviews] -[mainViewController viewDidLayoutSubviews] -[mainViewController viewDidAppear:] 

退出当前页面:

-[mainViewController viewWillDisappear:]
-[mainViewController viewDidDisappear:]

返回之前页面:

-[mainViewController viewWillAppear:]
-[mainViewController viewWillLayoutSubviews]
-[mainViewController viewDidLayoutSubviews]
-[mainViewController viewDidAppear:]

是否使用Core Text或者Core Image等?如果使用过,请谈谈你使用Core Text或者Core Image的体验。

CoreText
•   随意修改文本的样式
•   图文混排(纯C语言)
•   国外:Niumb
Core Image(滤镜处理)
* 能调节图片的各种属性(对比度, 色温, 色差等)

分析一下使用手机获取验证码注册账号的实现逻辑(给了一个示例图),发送到手机的验证码超过60秒钟后重新发送

你做iphone开发时候,有哪些传值方式,view和view之间是如何传值的?

block, target-action ,代理,属性

有哪几种手势通知方法、写清楚方法名?

-(void)touchesBegan:(NSSet)touchedwithEvent:(UIEvent)event;

-(void)touchesMoved:(NSSet)touched withEvent:(UIEvent)event;

-(void)touchesEnded:(NSSet)touchedwithEvent:(UIEvent)event;

-(void)touchesCanceled:(NSSet)touchedwithEvent:(UIEvent)event;

文章如有问题,请留言,我将及时更正。

满地打滚卖萌求赞,如果本文帮助到你,轻点下方的红心,给作者君增加更新的动力。

上一篇 下一篇

猜你喜欢

热点阅读