(1)Foundation对象与Core Foundation对象有什么区别?
- Foundation对象是OC对象,Core Foundation对象是C对象
- 数据类型之间的转换
ARC:bridge_retained(持有对象所有权,F->CF),bridge_transfer(释放对象所有权CF->F)
非ARC:__bridge
(2)编写一个函数,实现递归删除指定路径下的所有文件
+ (void)deleteFiles:(NSString *)path
{
//1.判断文件还是目录
NSFileManager *fileManager = [NSFileManager defaultManager];
BOOL isDir = NO;
BOOL isExist = [fileManager fileExistsAtPath:path isDirectory:&isDir];
if (isExist) {
//2.判断是不是目录
if (isDir) {
NSArray *dirArray = [fileManager contentsOfDirectoryAtPath:path error:nil];
NSString *subPath = nil;
for (NSString *str in dirArray) {
subPath = [path stringByAppendingPathComponent:str];
BOOL isSubDir = NO;
[fileManager fileExistsAtPath:subPath isDirectory:&isSubDir];
[self deleteFiles:subPath];
}
}else {
NSLog(@"%@",path);
[fileManager removeItemAtPath:path error:nil];
}
}else {
NSLog(@"你打印的是目录或者不存在");
}
}
(3)苹果是如何实现autoreleasepool的?
autoreleasepool以一个队列数组的形式实现,主要通过以下三个函数实现:
- objc_autoreleasepoolPush
- objc-autoreleasepoolPop
- objc-autorelease
看函数名就可以知道,对autoreleasepool分别执行了Push、Pop操作。销毁对象时执行release操作。
(4)objc使用什么机制管理对象的内存?
通过引用计数器(retainCount)的机制来决定对象是否需要释放。每次runloop完成一个循环的时候,都会检查对象的retainCount,如果retainCount为0,说明该对象没有地方需要继续使用了,可以释放掉了。
(5)内存管理的原则
- 只要还有人在使用这个对象,那么这个对象就不会被回收
- 只要你想使用这个对象,那么就应该让这个对象的引用计数器加1
- 当你不想使用这个对象时,应该让对象的引用计数器减1
- 谁创建,就由谁release
如果你通过alloc、new、copy来创建一个对象,当你不想用这个对象的时候就必须调用release或者autorelease让引用计数器减1
不是你创建的就不用你负责release - 谁retain,谁release
只要你调用了retain,无论这个对象如何生成,都需要调用release - 总结:有加就应该有减,曾让某个计数器加1,就应该让其在最后减1
(6)UITableView的性能优化,滑动的时候有种卡的感觉是为什么?怎么解决?
- 在使用第三方应用时,确经常遇到性能上的问题,普遍表现在滚动时比较卡,特别是cell中包含图片的情况时。
- 实际上针对性地优化一下就可以解决tableView滑动的时候卡顿的问题:
1、 使用不透明视图。不透明的视图可以提高渲染的速度,可以将cell及其子视图的opaque属性设置为YES(默认值)。
2、不要重复创建不必要的cell。UITableView只需要一屏幕的UITableViewCell对象即可。因此在cell不可见时,可以将其缓存起来,而在需要时继续使用它即可。注意:cell被重用时,需要调用setNeedsDisplayInRect:或setNeedsDisplay方法重绘cell。
3、减少动画效果的使用,最好不要使用insertRowAtIndexPaths:withRowAnimation:方法,而是直接调用reloadData方法。
4、减少视图的数目。Cell包含了textLable、detailTextLabel和imageView等view,而你还可以自定义一些视图放在它的contentView里,创建它会消耗较多资源,并且也影响渲染的性能。
5、cell包含图片,且数目较多,使用自定义的cell速度会比使用默认的要快。
6、不需要与用户交互时,使用CALayer,将内容绘制到layer上,然后对cell的contentView.layer调用addSubLayer:方法。
7、不要做多余的绘制工作。在实现drawRect:的时候,它的rect参数就是需要绘制的区域,这个区域之外的不需要进行绘制。
8、预渲染图层。在图形上下文中画,导出成UIImage对象,然后再绘制到屏幕上。(头像圆角,或者其他变形的时候,用图形上下文能提高性能。)异步绘制
9、不要阻塞主线程。tableView在更新数据时,整个界面卡住不动,完全不响应用户请求。常见的是网络请求,等待时间长待数秒。(解决方案:使用多线程,让子线程去执行这些函数或方法)
注意:当下载线程数超过2时,会显著影响主线程的性能。所以在不需要响应用户请求时,下载线程数可以增加到5,不建议再加了,以加快下载速度。如果用户正在交互,应把线程数量控制在2个以内。
10、提前计算并缓存好高度,因为heightForRowAtIndexPath调用非常频繁
11、选择正确的数据结构:学会选择对业务场景最合适的数据结构是写出高效代码的基础。
12、gzip/zip压缩:当从服务端下载相关附件时,可以通过gzip/zip压缩够再下载,使得内存更小,下载速度也更快。