** iOS 开发面试问题(一)传送门 **
** 1、Push Notification 是如何工作的?**
iOS消息推送机制
** 2、什么是 Runloop?**
对Runloop实在的理解和运用
深入理解RunLoop
** 3、Toll-Free Bridging 是什么?什么情况下会使用?**
在开发中时常要使用Core Foundation框架,例如Core Graphics、Core Text等,有时需要在CF指针和OC对象之间进行转换,,在转换中需要注意内存管理。在ARC环境下,编译器不能自动管理CF对象的内存,我们需要使用CFRelease将其手动释放。因此需要时可以使用 __bridge __bridge_transfer __bridge_retained进行桥接。
使用方法
- __bridge:CF和OC对象转化时只涉及对象类型不涉及对象所有权的转化
NSURL *url = [[NSURL alloc] initWithString:@"http://www.baidu.com"];
CFURLRef ref = (__bridge CFURLRef)url;
使用__bridge时,不管是从OC转换到CF还是从CF转换成OC,即内存的管理权(所有权)不随转换而转换,CF对象还是需要使用CFRelease(),OC对象由ARC自动管理。
- __bridge_transfer 、orCFBridgingRelease:在CF指针转换成OC对象时,将CF指针的所有权交给ARC管理,此时ARC就能自动管理该内存
- __bridge_retained or CFBridgingRetain:将OC对象转换成CF指针时,管理的所有交由使用者手动释放
NSURL *url = [[NSURL alloc] initWithString:@"http://www.baidu.com"];
CFURLRef ref = (__bridge_retained CFURLRef)url;
CFRelease(ref);
iOS里Toll-Free Bridging的桥接机制
** 4、当系统出现内存警告时会发生什么?**
- 会将不在当前窗口上的view暂时移除
- 如果放任内存警告,最终会导致软件强制被系统关闭
** 5、什么是 Protocol,Delegate 一般是怎么用的?**
理解协议与代理
协议:
协议是一个方法签名的列表,在其中可以定义若干个方法。根据配置,遵守该协议的类会去实现这个协议中规定的若干个方法。
代理:
代理是一个概念,它更像是一种关系,我要做某一个事情,但我自己不想去做这件事,我委托其他人帮我去做这件事。这个时候,这位其他人就是我的代理。
IOS学习之一个示例弄懂代理(delegate)和协议
** 6、autorelease 对象在什么情况下会被释放?**
分两种情况:手动干预释放和系统自动释放
- 手动干预释放就是指定autoreleasepool,当前作用域大括号结束就立即释放
for (int i = 0; i < 10000000; ++i) {
@autoreleasepool {
HYBTestModel *tempModel = [[HYBTestModel alloc] init];
// 临时处理
// ...
} // 出了这里,就会去遍历该自动释放池了
}
- 系统自动去释放:不手动指定autoreleasepool,Autorelease对象会在当前的 runloop 迭代结束时释放
- kCFRunLoopEntry(1):第一次进入会自动创建一个autorelease
- kCFRunLoopBeforeWaiting(32):进入休眠状态前会自动销毁一个autorelease,然后重新创建一个新的autorelease
- kCFRunLoopExit(128):退出runloop时会自动销毁最后一个创建的autorelease
黑幕背后的Autorelease
** 7、UIWebView 有哪些性能问题?有没有可替代的方案。**
UIWebView、WKWebView使用详解及性能分析
8、为什么 NotificationCenter 要 removeObserver? 如何实现自动 remove?
- 如果不移除的话,万一注册通知的类被销毁以后又发了通知,程序会崩溃.因为向野指针发送了消息
- 实现自动remove:通过自动释放机制,通过动态属性将remove转移给第三者,解除耦合,达到自动实现remove
NSNotification 线程管理以及自动注销开源方案个人感觉没必要实现自动remove,这篇文章我看的也是不走心。只要记住在页面出现的时候注册通知,页面消失时移除通知,一定要成双成对出现就OK 了。
** 9、当 TableView 的 Cell 改变时,如何让这些改变以动画的形式呈现?**
这里举个例子,点击cell以后以动画形式改变cell高度
@interface ViewController ()
@property (nonatomic, strong) NSIndexPath *index;
@end
@implementation ViewController
static NSString *ID = @"cell";
- (void)viewDidLoad {
[super viewDidLoad];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:ID];
cell.textLabel.text = [NSString stringWithFormat:@"%ld",(long)indexPath.row];
return cell;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return 20;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
if(self.index == indexPath){
return 120;
}
return 60;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
self.index = indexPath;
[tableView deselectRowAtIndexPath:indexPath animated:TRUE];
// 重点是这2句代码实现的功能
[tableView beginUpdates];
[tableView endUpdates];
}
** 10、什么是 Method Swizzle,什么情况下会使用?**
又是一个RunTime的考点
Objective-C Method Swizzling 的最佳实践
11、 为什么 UIScrollView 的滚动会导致 NSTimer 失效?
这是否滚动取决于timer加入到Run Loop中的Mode是什么。Mode主要是用来指定事件在运行循环中的优先级的,分为:
NSDefaultRunLoopMode(kCFRunLoopDefaultMode):默认,空闲状态
UITrackingRunLoopMode:ScrollView滑动时会切换到该Mode
UIInitializationRunLoopMode:run loop启动时,会切换到该mode
NSRunLoopCommonModes(kCFRunLoopCommonModes):Mode集合
苹果公开提供的Mode有两个:
NSDefaultRunLoopMode(kCFRunLoopDefaultMode)
NSRunLoopCommonModes(kCFRunLoopCommonModes)
在编程中:如果我们把一个NSTimer对象以NSDefaultRunLoopMode(kCFRunLoopDefaultMode)添加到主运行循环中的时候, ScrollView滚动过程中会因为mode的切换,而导致NSTimer将不再被调度。当我们滚动的时候,也希望不调度,那就应该使用默认模式。但是,如果希望在滚动时,定时器也要回调,那就应该使用common mode。
** 12、为什么当 Core Animation 完成时,layer 又会恢复到原先的状态?**
因为这些产生的动画只是假象,并没有对layer进行改变.那么为什么会这样呢,这里要讲一下图层树里的呈现树.呈现树实际上是模型图层的复制,但是它的属性值表示了当前外观效果,动画的过程实际上只是修改了呈现树,并没有对图层的属性进行改变,所以在动画结束以后图层会恢复到原先状态
让动画在完成后也不移除,并且停留在动画结束的状态可以这样:
alphaAnim.removedOnCompletion = NO;
alphaAnim.fillMode = kCAFillModeForwards;
图层的树状结构 这是个讲 iOS Animation的系列文章
** 13、你会如何存储用户的一些敏感信息,如登录的 token。**
使用Keychain存储用户敏感信息
14、 有用过一些开源组件吧,能简单说几个么,大概说说它们的使用场景实现。
这里给出两个知名度很高很常用的开源组件解析
关于AFNetworking 3.0
iOS程序猿之AFNetworking 3.0 版本使用
SDWebImage 原理及使用
SDWebImage的使用
15、 什么时候会发生 EXC BAD ACCESS 异常?
- 访问一个僵尸对象,访问僵尸对象的成员变量或者向其发消息
- 死循环
** 16、什么时候会使用 Core Graphics,有什么注意事项么?**
几个基本概念:
- UIKit:cocoa touch框架,高层次的框架,允许开发人员创建视图、窗口、按钮和其他UI组件。同时将一些低级别的API引入到易于使用的高级别API中。
- Quartz 2D:IOS上绘图的主要引擎,是一组二位绘图和渲染API。
- Core Graphics:它支持图形上下文、加载图像、绘制图像,等等。
- Core Animation 帮助开发者在IOS上实现动画的框架。
Core Graphics是基于C的API,可以用于一切绘图操作我们可以通过派生一个UIView的子类,获得它的上下文。在UIView中调用drawRect:方法时,会自动准备好一个图形上下文,可以通过调用UIGraphicsGetCurrentContext()来获取。 因为它是运行期间绘制图片,我们可以动态的做一些额外的操作。
使用Core Graphics,可以创建直线、路径、渐变、文字与图像等内容,并可以做变形处理。
Core Graphics教程1:入门
Core Graphics 框架学习笔记,以及demo
** 17、NSNotification 和 KVO 的使用场景?**
iOS KVC & KVO
** 18、使用 Block 时需要注意哪些问题?**
在block内部使用外部指针且会造成循环引用情况下,需要用__weak
修饰外部指针__weak typeof(self) weakSelf = self;在block内部如果调用了延时函数还使用弱指针会取不到该指针,因为已经被销毁了,需要在block内部再将弱指针重新强引用一下__strong typeof(self) strongSelf = weakSelf;
如果需要在block内部改变外部变量的话,需要在用__block
修饰外部变量
OS开发-语法篇-block详解
iOS OC语言: Block底层实现原理
** 19、performSelector:withObject:afterDelay: 内部大概是怎么实现的,有什么注意事项么?**
performSelector 和NSTimer使用注意事项
** 20、如何播放 GIF 图片,有什么优化方案么?**
IOS 播放动态Gif图片
** 21、使用 NSUserDefaults 时,如何处理布尔的默认值?(比如返回 NO,不知道是真的 NO 还是没有设置过) **
if([[NSUserDefaults standardUserDefaults] objectForKey:ID] == nil){
NSLog(@"没有设置");
}
NSUserDefaults的使用
** 22、有哪几种方式可以对图片进行缩放,使用 CoreGraphics 缩放时有什么注意事项?
**
ios中图片拉伸的几种方式
UIScrollView控件实现图片缩放功能
iOS中拉伸图片的几种方式
图片拉伸原理
** 23、哪些途径可以让 ViewController 瘦下来?**
- 把 Data Source 和其他 Protocols 分离出来(将UITableView或者UICollectionView的代码提取出来放在其他类中)
- 将业务逻辑移到 Model 中(和模型有关的逻辑全部在model中写)
- 把网络请求逻辑移到 Model 层(网络请求依靠模型)
- 把 View 代码移到 View 层(自定义View)
更轻量的 View Controllers
** 24、有哪些常见的 Crash 场景? **
比如数组越界、插空、空引用、引用未定义方法、访问野指针、发送未实现的selector等。
iOS Crash调试和Crash符号化