iOS面试笔试题iOS

iOS复习总结01

2017-02-06  本文已影响399人  Kean_Qi

1.冒泡排序或快速排序

int i, j, temp;
        int a[10]={28,27,36,45,9,10,4,55,45,6};
        for (i = 0; i < 10; i++)
        {
            scanf("%d,", &a[i]);
        }
        for (j = 0; j < 9; j++)
        {
            for (i = 0; i < 9 - j; i++)
            {
                if (a[i] > a[i + 1])
                {
                    temp = a[i];
                    a[i] = a[i + 1];
                    a[i + 1] = temp;
                }
            }
        }
        for (i = 0; i < 10; i++)
        {
            printf("%d,", a[i]);
        } 
        printf("\n");


2.计算阶乘

- (int)fact:(int)i {
    int t=1,j;
    for (j=1; j<=i; j++) {
        t=t*j;
        NSLog(@"%d! %d",j,t);
    }
    return t;
}

3.Cocoa Touch提供了几种Core ? Animation过渡类?

答:Cocoa Touch提供了4种Core:核心操作系统层(Core OS layer)、核心服务层(Core Services layer)、媒体层(Media layer)和可触摸层(Cocoa Touch layer)

Animation过渡类型,分别为:交叉淡化、推挤、显示和覆盖。
fade // 交叉淡化过渡(不支持过渡方向)
push // 新视图把旧视图推出去 moveIn // 新视图移到旧视图上面 reveal // 将旧视图移开,显示下面的新视图 cube // 立方体翻滚效果 oglFlip // 上下左右翻转效果 suckEffect // 收缩效果,如一块布被抽走(不支持过渡方向) rippleEffect // 滴水效果(不支持过渡方向) pageCurl // 向上翻页效果 pageUnCurl // 向下翻页效果 cameraIrisHollowOpen // 相机镜头打开效果(不支持过渡方向) cameraIrisHollowClose // 相机镜头关上效果(不支持过渡方向) 

4.iOS平台怎么做数据的持久化?coredata和sqlite有无必然联系?coredata是一个关系型数据吗?

答:
所谓的持久化,就是将数据保存到硬盘中,使得在应用程序或机器重启后可以继续访问之前保存的数据。在iOS开发中,数据持久化的方案有5种方案:

plist文件(属性列表)

preference(偏好设置)

NSKeyedArchiver(归档)

SQLite 3

CoreData


数据的持久化本质上都是就是写文件,但从逻辑上又分成很多种,比如写入沙盒,存到网络上,写入数据库。

core data是对sqlite的封装,因为sqlite是c语言的api,然而有人也需要obj-c的api,所以有了core data ,另外,core data不仅仅是把c的api翻译成oc的api,还提供了一些管理的功能,使用更加方便。

App升级之后数据库字段或者表有更改会导致crash,CoreData的版本管理和数据迁移变得非常有用,手动写sql语句操作还是麻烦一些。

CoreData不光能操纵SQLite,CoreData和iCloud的结合也很好,如果有这方面需求的话优先考虑CoreData。

CoreData并不是直接操纵数据库,比如:使用CoreData时不能设置数据库的主键,目前仍需要手动操作。

4.Object-c的类可以多重继承么?可以实现多个接口么?category是什么?重写一个类的方式用继承好还是分类好?为什么?

答: Object-c的类不可以多重继承;可以实现多个接口,通过实现多个接口可以完成C++的多重继承;Category是类别,一般情况用分类好,用Category去重写类的方法,仅对本Category有效,不会影响到其他类与原有类的关系。

5. #import跟#include有什么区别,@class呢?#import<>跟#import””有什么区别?

答: #import是Objective-C导入头文件的关键字,#include是C/C++导入头文件的关键字,使用#import头文件会自动只导入一次,不会重复导入,相当于#include和#pragma once;@class告诉编译器某个类的声明,当执行时,才去查看类的实现文件,可以解决头文件的相互包含;#import<>用来包含系统的头文件,#import””用来包含用户头文件。

6.属性readwrite,readonly,assin,retain,copy,nonatomic各是什么作用,在哪种情况下用?

答: readwrite是可读可写特性;需要生成getter方法和setter方法时

readonly是只读特性只会生成getter方法不会生成setter方法;不希望属性在类外改变

assign是赋值特性,setter方法将传入参数赋值给实例变量;仅设置变量时;

retain表示持有特性,setter方法将传入参数先保留,再赋值,传入参数的retaincount会+1;

copy表示拷贝特性,setter方法将传入对象复制一份;需要完全一份新的变量时。

nonatomic非原子操作,决定编译器生成的setter

getter是否是原子操作,atomic表示多线程安全,一般使用nonatomic

7.写一个setter方法用于完成

@property(nonatomic, retain)NSString *name;
@property(nonatomic, copy)NSString *name;

-(void)setName:(NSString *) str

{
    
    [str retain];
    
    [_name1 release];
    
    _name1 = str;
    
}

- (void)setName:(NSString *)str

{
    
    id t = [str copy];
    
    [_name release];
    
    _name = t;
}

9.对于语句NSString *obj =[[NSData alloc] init]; obj在编译时和运行时分别是什么类型的对象?

答:编译时是NSString的类型;运行时是NSData类型的对象

10.当前已经编程实现函数:int

rand100().该函数可返回0~99的随机整数,且可以保证等概率.请利用该函数实现int rand10000(),要求等概率返回0~9999的随机数.(不可使用其他的系统函数)

11. 汤姆现在要在家里举行宴会,他虽然有很多筷子,但这些筷子的长度并不完全相同,先已知每根筷子的长度,要求每位客人都能拿到两根长度相同的筷子,求最多可邀请的客人数.

编程实现:int getMax(int arrLength[N])

12.现有一个整数序列,你可以交换其中的任意两个数以得到一个新序列.求共能得到多少种可能结果.(注意:3,3,3,3无论怎么交换,只能得到一个序列)

编程实现:int getTotal(int arrOrigin[N])

13.现有一个M行N列的数组,要求安装反向斜对角线(右上->左下)的方式,打印该数组.编程实现:

intprintMatrix[int arrMatrix[M][N]]
下面样例的打印顺序为:

0->1->4->2->5->8->3->6->9->7->10->11

123

4567

8910 11

14.在UIKit中,frame与bounds的关系是

frame的参考系是父规图坐标, bounds的参考系是自身的坐标

15.一个类的delegate(代理)

A.delegate中的函数在其他类中实现

B.主要用于不同类型的对象之间一对一传递消息

C.没有指派则不会触发

16.关于Objective-C内存管理

A.当使用ARC来管理内存时,对象的retain,dealloc方法不会被调用

B.autoreleasepool在drain的时候会释放在其中分配的对象

C.当使用ARC来管理内存时,在线程中大量分配对象而不用autoreleasepool则可能会造成内存泄露

17.block定义

tyoedef void(^SuccessBlock)(BOOL success);

18.UIButton从子类到父类一次继承自

UIControl-> UIView-> UIResponder

19.关于iOS开发中类方法的使用描述

类方法可以调用类方法
类方法不可以调用实例方法,但是类方法可以通过创建对象来访问实例方法
类方法作为消息,可以被发送到类或者对象里面去

20.什么情况下使用关键字weak和assign,有何不同?

答:assign指针赋值,不对引用计数操作,使用之后如果没有置为nil,可能就会产生野指针;而weak一旦不进行使用后,永远不会使用了,就不会产生野指针!

21.如何用iOS设备进行性能测试

答: Profile-> Instruments ->Time Profiler

22.oc是动态运行时语音是什么意思

答案:多态。主要是将数据类型的确定由编译时,推迟到了运行时。这个问题其实浅涉及到两个概念,运行时和多态。简单来说,运行时机制使我们直到运行时才去决定一个对象的类别,以及调用该类别对象指定方法。多态:不同对象以自己的方式响应相同的消息的能力叫做多态。意思就是假设生物类(life)都用有一个相同的方法-eat;那人类属于生物,猪也属于生物,都继承了life后,实现各自的eat,但是调用是我们只需调用各自的eat方法。也就是不同的对象以自己的方式响应了相同的消息(响应了eat这个选择器)。因此也可以说,运行时机制是多态的基础。

23.你的项目什么时候选择使用GCD,什么时候选择NSOperation

项目中使用NSOperation的优点是NSOperation是对线程的高度抽象,在项目中使用它,会使项目的程序结构更好,子类化NSOperation的设计思路,是具有面向对象的优点(复用、封装),使得实现是多线程支持,而接口简单,建议在复杂项目中使用。NSOperation/NSOperationQueue是给予GCD做的封装,使用较重,在某些情境下性能不如GCD,但在并发环境下复杂任务处理能很好地满足一些特性,业务扩展性较好。
项目中使用GCD的优点是GCD本身非常简单、易用,对于不复杂的多线程操作,会节省代码量,而Block参数的使用,会是代码更为易读,建议在简单项目中使用

24.读文件是输入流还是输出流?

信息读入内存就是输入流。
信息从内存写到记录存储属于输出流。
而我们本身就以记录存储为原点所以会有不解的感觉。
java io流按照java io流的方向可以分为输入流和输出流。
输入流是将资源数据读入到缓冲Buffer中,输出流是将缓冲Buffer中的数据按照指定格式写出到一个指定的位置,所以这两个流一般同时使用,才有意义。
例如你要做文件的上传,你要先用输入流将待上传文件读入缓冲,然后用输出流将文件写出到网络服务器的一个位置,则上传成功;
若是文件下载,则先获得输入流,来读取网络服务器中的一个文件,然后用输出流写到本地的一个文件中;
还有例如文件的拷贝,也是先用输入流读再用输出流写出去。

25.简述CALayer和UIView的关系

答:UIView和CALayer是相互依赖的关系。
UIView依赖与calayer提供的内容,CALayer依赖uivew提供的容器来显示绘制的内容。
归根到底CALayer是这一切的基础,如果没有CALayer,UIView自身也不会存在,UIView是一个特殊的CALayer实现,添加了响应事件的能力。
结论:

UIView来自CALayer,高于CALayer,是CALayer高层实现与封装。UIView的所有特性来源于CALayer支持。

26.声明一个静态方法和一个实例方法

答:先说实例方法,当你给一个类写一个方法,如果该方法需要访问某个实例的成员变量时,那么就将该方法定义成实例方法。一类的实例通常有一些成员变量,其中含有该实例的状态信息。而该方法需要改变这些状态。那么该方法需要声明成实例方法。

静态方法正好相反,它不需要访问某个实例的成员变量,它不需要去改变某个实例的状态。我们把该方法定义成静态方法。

27.常见的Object-C的数据类型有哪些?和Cd基本数据类型有什么区别?

答: Object-C的数据类型有NSString,NSNumber,NSArray,NSMutablearray,NSData等等,这些都是Class,创建后便是对象,而c语言的基本数据类型int,只是一定字节的内存空间,用于存放数值;而Object-C的NSNumber包含有父NSObject的方法和NSNumber自己的方法,可以完成复杂的操作。

28..UIView的动画效果有哪些

如UIViewAnimationOptionCurveEaseInOut

UIViewAnimationOptionCurveEaseIn

UIViewAnimationOptionCurveEaseOut

UIViewAnimationOptionTransitionFlipFromLeft

UIViewAnimationOptionTransitionFlipFromRight

UIViewAnimationOptionTransitionCurlUp

UIViewAnimationOptionTransitionCurlDown

29.静态链接库

答:静态库是程序代码的集合,是共享代码的一种方式

静态库是闭源的存在形式.a和.framework

连接时,静态库会被完全的复制到可执行文件中,被多次使用就会有冗余拷贝,相当于java里的jar包,把一些类编译到一个包中,在不同的工程中如果导入此文件就可以使用里面的类,

30.什么是沙箱模型?哪些操作是属于私有api范畴?

答:
1、应用程序可以在自己的沙盒里运作,但是不能访问任何其他应用程序的沙盒。

2、应用程序间不能共享数据,沙盒里的文件不能被复制到其他应用程序文件夹中,也不能把其他应用程序文件夹中的文件复制到沙盒里。

3、苹果禁止任何读、写沙盒以外的文件,禁止应用程序将内容写到沙盒以外的文件夹中。

4、沙盒根目录里有三个文件夹:
Documents:一般应该把应用程序的数据文件存到这个文件夹里,用于存储用户数据或其他应该定期备份的信息。
Library:下有两个文件夹  ①Caches存储应用程序再次启动所需的信息  ②Preferences包含应用程序偏好设置文件,不过不要在这里修改偏好设置。
temp:存放临时文件,即应用程序再次启动不需要的文件。

沙盒根目录里有三个文件夹分别是:documents,tmp,Library。

1、Documents目录:您应该将所有的应用程序数据文件写入到这个目录下。这个目录用于存储用户数据或其它应该定期备份的信息。

2、AppName.app目录:这是应用程序的程序包目录,包含应用程序的本身。由于应用程序必须经过签名,所以您在运行时不能对这个目录中的内容进行修改,否则可能会使应用程序无法启动。

3、Library目录:这个目录下有两个子目录:Caches和Preferences

Preferences目录:包含应用程序的偏好设置文件。您不应该直接创建偏好设置文件,而是应该使用NSUserDefaults类来取得和设置应用程序的偏好.

Caches目录:用于存放应用程序专用的支持文件,保存应用程序再次启动过程中需要的信息。

4、tmp目录:这个目录用于存放临时文件,保存应用程序再次启动过程中不需要的信息。

iOS沙盒(sandbox)中的几个目录获取方式:

//获取沙盒主目录路径

NSString *homeDir = NSHomeDirectory();

//获取Documents目录路径

NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);

NSString *docDir = [paths objectAtIndex:0];

//获取Caches目录路径

NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);

NSString *cachesDir = [paths objectAtIndex:0];

//获取tmp目录路径

NSString *tmpDir =  NSTemporaryDirectory();

//获取当前程序包中一个图片资源(apple.png)路径

NSString *imagePath = [[NSBundle mainBundle] pathForResource:@"apple" ofType:@"png"];

UIImage *appleImage = [[UIImage alloc] initWithContentsOfFile:imagePath];

例子:

NSFileManager* fm=[NSFileManager defaultManager];

if(![fm fileExistsAtPath:[self dataFilePath]]){

//下面是对该文件进行制定路径的保存

[fm createDirectoryAtPath:[self dataFilePath] withIntermediateDirectories:YES attributes:nil error:nil];

//取得一个目录下得所有文件名

NSArray *files = [fm subpathsAtPath: [self dataFilePath] ];

//读取某个文件

NSData *data = [fm contentsAtPath:[self dataFilePath]];

//或者

NSData *data = [NSData dataWithContentOfPath:[self dataFilePath]];

}

31.协议是什么?有什么作用?

协议:声明一系列的方法,可由任何类实施,即使遵守该协议的类没有共同的超类。协议方法定义了独立于任何特定类的行为。简单的说,协议就是定义了一个接口,其他类负责来实现这些接口。如果你的类实现了一个协议的方法时,则说该类遵循此协议。

协议的作用:

1.定义一套公用的接口(Public)

@required:必须实现的方法

@optional:可选实现的方法(可以全部都不实现)

2.委托代理(Delegate)传值:

它本身是一个设计模式,它的意思是委托别人去做某事。

比如:两个类之间的传值,类A调用类B的方法,类B在执行过程中遇到问题通知类A,这时候我们需要用到代理(Delegate)。

又比如:控制器(Controller)与控制器(Controller)之间的传值,从C1跳转到C2,再从C2返回到C1时需要通知C1更新UI或者是做其它的事情,这时候我们就用到了代理(Delegate)传值。

32.你在开发大型项目时,如何进行内存泄露检测的?

可以通过xcode的自带工具run---start with performance tool里有instruments下有个leaks工具,

启动此工具后,运行项目,工具里可以显示内存泄露的情况,双击可找到源码位置,可以帮助进行内存泄露的处理。

33.你实现过一个框架或者库以供别人使用么?如果有,请谈一谈构建框架或者库是的经验;如果没有,请设想和设计框架的public的API,并指出大概需要如何做,需要注意一些什么方面,来方便别人容易地使用你的框架.

待解 

34.app从创建应用到上架过程(appstore)

在你开始将程序提交到App Store之前,你需要有一个App ID,一个有效的发布证书,以及一个有效的Provisioning profile。
在itunesconnect网站上,创建app应用,设置对应信息,上传app打包文件,提交等待审核

35.用你熟悉的语音,编程实现Fibonacci数列:int F(intn);

//著名的Fibonacci数列 斐波那契数列
- (int)fibonacci:(int)n {
    //f(0)==0 f(1)=1,f(2)=1,f(n)=f(n-1)+f(n-2),n>2
    //0,1,1,2,3,5,8,13,21
    if (n==0) {
        return 0;
    } else if (n==1) {
        return 1;
    } else if(n==2){
        return 1;
    }
    return [self fibonacci:n-1] + [self fibonacci:n-2];
}

36.给定两个排好序的数组A,B,请写一个函数,从中找出他们的公共元素:findCommon(A,B)并列举其他可能的查找方法,越多越好


/*
 Array A = [1, 3, 5, 6, 9]
 
 Array B = [2, 3, 6, 8, 10]
 
 返回结果= [3, 6]
 */

- (NSMutableArray *)findCommonArray1:(NSArray *)array1 Array2:(NSArray*)array2 {
    NSMutableArray *array = [NSMutableArray array];
    int i=0,j=0;
    while (i<array1.count && j<array2.count) {
        int arr1 = [array1[i] intValue];
        int arr2 = [array2[j] intValue];
        if (arr1<arr2) {
            ++i;
            
        } else if (arr1 == arr2) {
            NSLog(@"%@",array1[i]);
            [array addObject:array1[i]];
            ++i;
            ++j;
        } else if(arr1 > arr2){
            ++j;
        }
    }
    NSLog(@"%@",array);
    return array;
}

37.KVO的实现原理?

KVO:当指定的对象的属性被修改了,允许对象接收到通知的机制
KVO:键值监听,观察某一属性的方法

38.如何给一个对象的私有属性赋值?

利用KVC即键值编码来给对象的私有属性赋值.
KVC:键值编码,是一种间接访问对象的属性

39.block的本质是什么?为啥在block里面更改外面变量的值,要给外面的变量加_block修饰,加_block修饰的原理是什么?

答: (1) block本质是一个数据类型,多用于参数传递,代替代理方法, (有多个参数需要传递或者多个代理方法需要实现还是推荐使用代理方法),少用于当做返回值传递. block是一个OC对象,它的功能是保存代码片段,预先准备好代码,并在需要的时候执行.

(2)因为使用block代码块可能会引起内部循坏引用,所以应在block定义前加上修饰

40.block在哪种情况下会造成循环引用,如何解决?

答:(1)从两方面分析造成循环引用问题

当self拥有一个block的时候,在block又调用self的方法(或者self所拥有的某个属性)。形成你中有我,我中有你,这种时候会造成循环引用

把某个实例变量变成本地临时变量,强引用将直接指向这个本地临时变量,但本地临时变量一般都会很快释放,所以一般考虑第一种情况

(2)解决方案:对block进行修饰__weak(arc)或__block(mrc)

41.NSURLSession在什么情况下回存在循环引用的问题,怎么解决?

答: (1)在使用NSURLSession签订其代理的时候会存在循环引用问题,因为其代理是retain强引用

(2)解决方案

(1)在下载完成后取消NSURLSession会话并释放Session,赋值为nil。

(2)在视图将要消失时也执行同样的操作。为了防止没有下载完成就跳转控制器。

具体如下:

/**视图将要消失的时候,取消session*/

- (void)viewWillDisappear:(BOOL)animated

{

[super viewWillDisappear:animated];

//任务完成,取消NSURLSession

[self.session invalidateAndCancel];

//释放会话

self.session =nil;

}

42.如何自己实现GET缓存?

答:1.使用GET请求数据

2.iOS系统SDK已经做好了缓存。需要的仅仅是设置下内存缓存大小、磁盘缓存大小、以及缓存路径,代码如下

NSURLCache *urlCache = [[NSURLCache alloc] initWithMemoryCapacity:4 * 1024 * 1024 diskCapacity:20 * 1024 * 1024 diskPath:nil];

[NSURLCache setSharedURLCache:urlCache];

43.在使用SQLite过程中,如果多条线程同时操作同一数据库会造成什么问题,怎么解决?

答:(1)容易造成系统崩溃

(2)解决方案:开启第3种串行模式,使用一个类(单例方式)操作数据库。

44.如果提交一个Json格式的数据给后台服务器,后台服务器返回的是一段普通文字,用NSURLConnection/NSURLSession/AFN分别如何实现?

1.使用NSURLConnection发送请求的步骤很简单

(1)创建一个NSURL对象,设置请求路径(设置请求路径)

(2)传入NSURL创建一个NSURLRequest对象,设置请求头和请求体(创建请求对象)

(3)使用NSURLConnection发送NSURLRequest(发送请求)
2.使用NSURLSession发送请求的步骤很简单

1)确定请求路径(一般由公司的后台开发人员以接口文档的方式提供),GET请求参数直接跟在URL后面

2)创建请求对象(默认包含了请求头和请求方法【GET】),此步骤可以省略

3)创建会话对象(NSURLSession)

4)根据会话对象创建请求任务(NSURLSessionDataTask)

5)执行Task

6)当得到服务器返回的响应后,解析数据(XML|JSON|HTTP)
3.AFN类似

45.请描述一下SDWebImage内部实现的原理

答:SDWebImage底层实现有沙盒缓存机制,主要由三块组成

1、内存图片缓存

2、内存操作缓存

3、磁盘沙盒缓存

46.你对runtime都有哪些了解,你在实现开发过程中,或是你在所使用的第三方框架中,有没有使用过runtime的,如果有,请你描述一下其内部实现机制. message send如果寻找不到响应的对象,会如何?

Runtime:runtime是一套比较底层的纯C语言API,属于1个C语言库,包含了很多底层的C语言API。在我们平时编写的OC代码中,程序运行过程时,其实最终都是转成了runtime的C语言代码, runtime算是OC的幕后工作者.
Objc Runtime其实是一个Runtime库,它基本上是用C和汇编写的,这个库使得C语言有了面向对象的能力

47.线程间怎么通信?

(1)GCD:

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0), ^{

//下载图片

UIImage *image = nil;

dispatch_async(dispatch_get_main_queue(),^{

//回到主线程

});

(2)NSThread的线程通信

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0), ^{

//下载图片

UIImage *image = nil;

[selfperformSelector:@selector(settingImage:) onThread:[NSThread mainThread]withObject:image waitUntilDone:YES modes:nil];

}

这种情况也适用于子线程之间的通信。

48.网络图片处理问题中怎么解决一个相同的网络地址重复请求的问题?

利用字典图片地址为key,下载操作为value

49.自动释放池底层怎么实现?

自动释放池以栈的形式实现:
当你创建一个新的自动释放池时,它将被添加到栈顶.
当一个对象收到发送autorelease消息时,他被添加到当前线程的处于栈顶的自动释放池中.
当自动释放池被回收时,他们从栈中被删除,并且会给池子里面所有的对象都会做一次release操作.

50.不用中间变量,用两种方法交换A和B的值

 A   B
A = A+B;

B = A - B;

A = A - B;

50.简单描述一下客户端的缓存机制?

图50-1
图50-2缓存数据的过程
一、关于同一个URL的多次请求
有时候,对同一个URL请求多次,返回的数据可能都是一样的,比如服务器上的某张图片,无论下载多少次,返回的数据都是一样的。
上面的情况会造成以下问题
(1)用户流量的浪费
(2)程序响应速度不够快
解决上面的问题,一般考虑对数据进行缓存。
二、缓存
为了提高程序的响应速度,可以考虑使用缓存(内存缓存\硬盘缓存)
客户端  --检测有无缓存-->  内存缓存  --检测有无缓存-->  磁盘缓存 --请求--> 服务器
图50-1
第一次请求数据时,内存缓存中没有数据,硬盘缓存中没有数据。
图50-2
缓存数据的过程
当服务器返回数据时,需要做以下步骤

(1)使用服务器的数据(比如解析、显示)

(2)将服务器的数据缓存到硬盘(沙盒)

此时缓存的情况是:内存缓存中有数据,硬盘缓存中有数据。

再次请求数据分为两种情况:

(1)如果程序并没有被关闭,一直在运行

  那么此时内存缓存中有数据,硬盘缓存中有数据。如果此时再次请求数据,直接使用内存缓存中的数据即可

(2)如果程序重新启动

  那么此时内存缓存已经消失,没有数据,硬盘缓存依旧存在,还有数据。如果此时再次请求数据,需要读取内存中缓存的数据。

提示:从硬盘缓存中读取数据后,内存缓存中又有数据了

三、缓存的实现

1.说明:

由于GET请求一般用来查询数据,POST请求一般是发大量数据给服务器处理(变动性比较大)

因此一般只对GET请求进行缓存,而不对POST请求进行缓存

  在iOS中,可以使用NSURLCache类缓存数据

  iOS 5之前:只支持内存缓存。从iOS 5开始:同时支持内存缓存和硬盘缓存

 

2.NSURLCache

iOS中得缓存技术用到了NSURLCache类。

缓存原理:一个NSURLRequest对应一个NSCachedURLResponse

缓存技术:把缓存的数据都保存到数据库中。

 

3.NSURLCache的常见用法

(1)获得全局缓存对象(没必要手动创建)NSURLCache *cache = [NSURLCache sharedURLCache]; 

(2)设置内存缓存的最大容量(字节为单位,默认为512KB)- (void)setMemoryCapacity:(NSUInteger)memoryCapacity;

(3)设置硬盘缓存的最大容量(字节为单位,默认为10M)- (void)setDiskCapacity:(NSUInteger)diskCapacity;

(4)硬盘缓存的位置:沙盒/Library/Caches

(5)取得某个请求的缓存- (NSCachedURLResponse *)cachedResponseForRequest:(NSURLRequest *)request; 

(6)清除某个请求的缓存- (void)removeCachedResponseForRequest:(NSURLRequest *)request;

(7)清除所有的缓存- (void)removeAllCachedResponses;

 

4.缓存GET请求

  要想对某个GET请求进行数据缓存,非常简单

  NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];

  // 设置缓存策略

  request.cachePolicy = NSURLRequestReturnCacheDataElseLoad;

  只要设置了缓存策略,系统会自动利用NSURLCache进行数据缓存

 

5.iOS对NSURLRequest提供了7种缓存策略:(实际上能用的只有4种)

NSURLRequestUseProtocolCachePolicy // 默认的缓存策略(取决于协议)

NSURLRequestReloadIgnoringLocalCacheData // 忽略缓存,重新请求

NSURLRequestReloadIgnoringLocalAndRemoteCacheData // 未实现

NSURLRequestReloadIgnoringCacheData = NSURLRequestReloadIgnoringLocalCacheData // 忽略缓存,重新请求

NSURLRequestReturnCacheDataElseLoad// 有缓存就用缓存,没有缓存就重新请求

NSURLRequestReturnCacheDataDontLoad// 有缓存就用缓存,没有缓存就不发请求,当做请求出错处理(用于离线模式)

NSURLRequestReloadRevalidatingCacheData // 未实现

 

6.缓存的注意事项

缓存的设置需要根据具体的情况考虑,如果请求某个URL的返回数据:

  (1)经常更新:不能用缓存!比如股票、彩票数据

  (2)一成不变:果断用缓存

  (3)偶尔更新:可以定期更改缓存策略 或者 清除缓存

提示:如果大量使用缓存,会越积越大,建议定期清除缓存

四、简单的代码示例
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    // 1.创建请求
    NSURL *url = [NSURL URLWithString:@"http://127.0.0.1:8080/YYServer/video"];
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
    
    // 2.设置缓存策略(有缓存就用缓存,没有缓存就重新请求)
    request.cachePolicy = NSURLRequestReturnCacheDataElseLoad;
    
    // 3.发送请求
    [NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
        if (data) {
            NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableLeaves error:nil];
            
            NSLog(@"%@", dict);
        }
    }];
}

/**
 // 定期处理缓存
 //    if (缓存没有达到7天) {
 //        request.cachePolicy = NSURLRequestReturnCacheDataElseLoad;
 //    }
 // 获得全局的缓存对象
 NSURLCache *cache = [NSURLCache sharedURLCache];
 //    if (缓存达到7天) {
 //        [cache removeCachedResponseForRequest:request];
 //    }
 
 // lastCacheDate = 2014-06-30 11:04:30
 
 NSCachedURLResponse *response = [cache cachedResponseForRequest:request];
 if (response) {
 NSLog(@"---这个请求已经存在缓存");
 } else {
 NSLog(@"---这个请求没有缓存");
 }
 */

51.控制器View的生命周期及相关函数是什么?你在开发中是如何用的?

>1.在视图显示之前调用viewWillAppear;该函数可以调用多次;

>2.视图显示完毕,调用viewDidAppear;

>3.在视图消失之前调用viewWillDisAppear;该函数可以调用多次(如需要);

>4.在布局变化前后,调用viewWill/DidLayoutSubviews处理相关信息;

52.NSRunLoop的实现机制,及在多线程中如何使用?

答案:NSRunLoop是iOS的消息机制的处理模式

>1NSRunloop的主要作用:控制runloop里面线程的执行和休眠,在有事情做的时候使挡墙NSRunloop控制的线程工作,没有事情做让当前runloop的控制线程休眠.

>2.runloop就是一直在循环检测,从线程start到线程end,检测inputsourse(如点击,双击等操作)异步时间,检测timesourse同步事件,见到检测到输入源会执行处理函数,首先会产生通知,corefunction向线程添加runloop observers来监听事件,意在监听事件发生时来做处理。

>3.runloopmode是一个集合,包括监听:事件源,定时器,以及需通知的runloop observers

>1.只有在为你的程序创建多线程的时候,才需要运行run loop。对于程序的主线程而言,run loop是关键部分。Cocoa提供了运行主线程run loop的代码同时也会自动运行run loop。IOS程序UIApplication中的run方法在程序正常启动的时候就会启动run loop。如果你使用xcode提供的模板创建的程序,那你永远不需要自己去启动run loop

>2.在多线程中,你需要判断是否需要run loop。如果需要run loop,那么你要负责配置run loop并启动。你不需要在任何情况下都去启动run loop。比如,你使用线程去处理一个预先定义好的耗时极长的任务时,你就可以毋需启动run loop。Run loop只在你要和线程有交互时才需要

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

进入main函数,在main.m的main函数中执行了UIApplicationMain这个方法,这是ios程序的入口点!

int UIApplicationMain(int argc, char argv[], NSString principalClassName, NSString *delegateClassName)

argc、argv:ISO C标准main函数的参数,直接传递给UIApplicationMain进行相关处理即可

principalClassName:指定应用程序类,该类必须是UIApplication(或子类)。如果为nil,则用UIApplication类作为默认值

delegateClassName:指定应用程序类的代理类,该类必须遵守UIApplicationDelegate协议

此函数会根据principalClassName创建UIApplication对象,根据delegateClassName创建一个delegate对象,并将该delegate对象赋值给UIApplication对象中的delegate属性

UIApplication对象会依次给delegate对象发送不同的消息,接着会建立应用程序的main runloop(事件循环),进行事件的处理(首先会调用delegate对象的application:didFinishLaunchingWithOptions:)

程序正常退出时这个函数才返回。如果进程要被系统强制杀死,一般这个函数还没来得及返回进程就终止了

54.第三方API你是怎么用的?

1.cocoa pod导入
2.文件直接导入

55.用预处理指令#define声明一个常数,用以表明一年中有多少秒?(忽略闰年问题)

#define second 365*24*60*60

56.UITableView需要实现哪些代理?列出UITableView代理中必须实现的与其他一些常用的函数.

//一组有多少行
-( NSInteger )tableView:( UITableView *)tableViewnumberOfRowsInSection:( NSInteger)section;

//每行中的cell的实现
-( UITableViewCell *)tableView:( UITableView *)tableViewcellForRowAtIndexPath:(NSIndexPath *)indexPath;
----以上两个方法为必须要实现的

//选中以后事件设置
- ( void )tableView:( UITableView *)tableViewdidSelectRowAtIndexPath:( NSIndexPath*)indexPath

//设置cell的高度
-( CGFloat )tableView:( UITableView *)tableViewheightForRowAtIndexPath:( NSIndexPath*)indexPath

57.在iOS上开发一个应用程序时怎么做的?

首先,要有一个MAC系统(买一台苹果电脑,苹果本或者MACmini),没有这个条件可以装一个黑苹果的mac系统或者装一个虚拟机。然后装一个X-CODE开发环境。要是学习ios开发的话,这些就可以了。如果要开发、上线的话,就得准备iphone/ipod、ipad做为测试机,到苹果申请一个开发者账号,每年的年费99美元。再然后接着就可以开发你的程序了,开发完毕之后,发布到App store上面,通过审核就可以了。

58.iOS中的数据持久化方式

属性列表、对象归档、SQLite和CoreData、对象归档

59.常见的object-c的数据类型有哪些,和C的基本数据类型有什么区别?如:NSInteger和int

object的数据类型由NSString,NSNumber,NSArray,NSMutableArray,NSData等等,这些都是class,创建后便是对象,而C语言的基本数据类型int,只是一定字节的内存空间,用于存放数值,NSInteger是基本的数据类型,并不是NSNumber的子类,当然也不是NSObject的子类。NSInteger是基本数据类型int或者Long的别名(NSInteger的定义typedef long NSInteger)它的区别在于,NSInteger会根据系统是32位还是64位来决定是本身int还是long.

60.iOS有垃圾回收机制吗?它是以怎样的机制来工作的?

OC是支持垃圾回收机制的(Garbage collection简称GC),但是apple的移动终端中,是不支持GC的,Mac桌面系统开发中是支持的.
移动终端开发是支持ARC(AutomaticReference Counting的简称),ARC是在IOS5之后推出的新技术,它与GC的机制是不同的。我们在编写代码时,不需要向对象发送release或者autorelease方法,也不可以调用delloc方法,编译器会在合适的位置自动给用户生成release消息(autorelease),ARC的特点是自动引用技术简化了内存管理的难度.

61.请使用gcd完成如下任务,执行并发任务task1,task1完成后update UI.

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0), ^{

//task1:

NSLog(@"执行task1");

//更新UI

dispatch_async(dispatch_get_main_queue(), ^{

NSLog(@"更新UI");

});

});

62.为什么在主线程中更新UI?子线程中想要更新UI怎么做?

(1)在子线程中不能更新UI,除了极少数UI外,其他UI更新要等到子线程执行完毕后回到主线程中进行更新。如果子线程一直在运行,则子线程中UI更新的函数栈主线程无法得知,即UI无法更新;

(2)回到主线程中进行UI更新;

63.简述通过Storyboard实现一个tableView

(自定义cell的关键步骤).

答:首先创建自己的自定义cell的类,我们叫做CustomCell,要继承于UITableViewCell。在这个类中定义自己所需要的控件。

然后,打开storyboard,选择自己要添加自定义cell的UIViewController,我们叫它为ViewController。在UITableView里面添加一个cell(或者修改原有的cell)。将cell的style改为custom,将cell的类改为CustomCell,将identifier改为CustomCellIdentifier。然后,可以在cell中添加控件,将控件和刚才在CustomCell中定义的控件连起来。

最后,在ViewController的UITableView的tableView:cellForRowAtIndexPath:代理方法中添加以下代码:
CustomCell*cell=[tableViewdequeueReusableCellWithIdentifier:@"CustomCellIdentifier"];

这样,就创建了一个cell,可以在这句代码之后对自己添加的控件进行设置。

64.如何生成同时支持多个架构(simulator,arm7,arm64)的通用静态库?

ValidArchitectures设置为:armv7|armv7s|arm64|i386|x86_64;

Architectures设置不变(或根据你需要):armv7|arm64;

然后分别选择iOS设备和模拟器进行编译,最后找到相关的.a进行合包,使用lipo -create真机库.a的路径模拟器库.a的的路径-output合成库的名字.a;

这样就制作了一个通用的静态库.a;

65.请写出一个xml文件,用于描述一个书架,书架上有2本书,书本的类别(category)分别是cooking,children.要求tag中包含书名(title),作者(author).类别(category)要用属性表示.

书名1<\title>

作者1<\author>

<\book>

书名2<\title>

作者2<\author>

<\book>

66.strcpy和memcpy的最大区别是什么?

1、复制的内容不同。strcpy只能复制字符串,而memcpy可以复制任意内容,例如字符数组、整型、结构体、类等。

2、复制的方法不同。strcpy不需要指定长度,它遇到被复制字符的串结束符"\0"才结束,所以容易溢出。memcpy则是根据其第3个参数决定复制的长度。

3、用途不同。通常在复制字符串时用strcpy,而需要复制其他类型数据时则一般用memcpy

67.g++, ld是什么?声明编译选项–DSUPPORT_BLUETOOTH =1有什么作用?

g++是GNU的c++编译器;

68.@class用途 delegate使用assign or retain简述理由.

@class一般用于头文件中声明某个类的实例变量的时候用到.它只是声明,至于内部的实现是没有告诉编译器的.
assign,防止出现循环引用;

69.NSString与NSData之间的转换过程中要特别注意的事项是什么?

NSString转换成NSData对象

NSData* xmlData = [@"testdata"dataUsingEncoding:NSUTF8StringEncoding];

NSData转换成NSString对象

NSData * data;

NSString *result = [[NSString alloc] initWithData:data  encoding:NSUTF8StringEncoding];

NSData转换成char*

NSData *data;

char *test=[data bytes];

char*转换成NSData对象

byte* tempData = malloc(sizeof(byte)*16);

NSData *content=[NSData dataWithBytes:tempData length:16];

转换过程中要注意NSData的编码格式问题.

解决方法:

先设置断点然后在控制台po出NSData的变量,看看会显示什么。

如果po出的NSData是可阅读的,直接能看到文本的内容,则使用[NSString stringWithFormat:NSData] (这里的NSData指的是你需要转换成NSString的NSData变量)即可。

如果po出的NSData是不可阅读的乱码,那一般都是有编码格式的,最常用的是NSUTF8StringEncoding,另外还有NSASCIIStringEncoding等,你可以在Apple文档里找到编码格式的那个枚举类型,挨个尝试。

70.请用代码如何判断某个对象obj是否支持某个method.

if ([self respondsToSelector:@selector(print:)]) {

[self print:@"支持这个方法"];

}

71.请用简单的代码展示@protocol的定义及实现.

#pragma mark - 代理第一步:声明协议

@protocol MarryMe

-(void)makeMoney;

@end

#pragma mark - 代理第二步:声明代理

@property(nonatomic,assign)id myDeleget;

.m文件中

#pragma mark - 代理第三步:代理人执行协议方法

[self.myDeleget makeMoney];

代理人.m文件中

#pragma mark - 代理第四步:签订协议

@interface Boy : NSObject

Girl *girl = [[Girl alloc] init];

#pragma mark - 代理第五步:成为代理人

girl.myDeleget = self;

[girl getMessage:message];

#pragma mark - 协议代理第六步:实现协议方法

-(void)makeMoney{

NSLog(@"aaa");

}

72.3升的杯子一个,5升的杯子一个,杯子的形状不规则,问怎么才能得到4升的水,水无限多.(请写出推理过程)

先将5升的杯子倒满,然后把5升的杯子中的水倒入3升的杯子,倒满后5升的杯子剩下2升.再把3升杯子中的水倒掉,把5升的杯子中剩余的2升水倒入3升的杯子中,然后把5升的杯子倒满.再用5升的杯子中的水给3升的杯子添满,则5升的杯子中剩余4升的水.

73.网络通信用过哪些方式?

ios设备的网络通信的方法,有如下两个大类:

1、使用socket的方式进行通信。

2、使用asynsocket类库进行通信。

74.如何处理多个网络请求并发的情况?

当有多个线程在操作时,如果系统只有一个CPU,则它根本不可能真正同时进行一个以上的线程,它只能把CPU运行时间划分成若干个时间段,再将时间段分配给各个线程执行,在一个时间段的线程代码运行时,其它线程处于挂起状。.这种方式我们称之为并发(Concurrent)。

遇到这种情况建议使用第三方的网络库。比如AFNetworking。也可以通过GCD和NSOperationQueue来控制并发

75.UINavigationController如何要使用push/pop功能的话,需要怎么实现

1.用UINavigationController的时候用pushViewController:animated

----返回之前的视图[[self navigationController] popViewControllerAnimated:YES];

---ps:push以后会在navigation的left bar自动添加back按钮,它的响应方法就是返回。所以一般不需要写返回方法,点back按钮即可。

2.其他时候用presentModalViewController:animated

[self presentModalViewController:controller animated:YES];//YES有动画效果

-----返回之前的视图[self dismissModalViewControllerAnimated:YES];

3.切换视图一般用不到addSubview

UINavigationController是导航控制器,如果pushViewController的话,会跳转到下一个ViewController,点返回会回到现在这个ViewController;

如果是addSubview的话,其实还是对当前的ViewController操作,只是在当前视图上面又“盖”住了一层视图,其实原来的画面在下面呢,看不到而已。

76.UIView如何需要重新绘制整个界面,需要调用什么方法?

UIView setNeedsDisplay和setNeedsLayout方法。首先两个方法都是异步执行的。而setNeedsDisplay会调用自动调用drawRect方法,这样可以拿到UIGraphicsGetCurrentContext,就可以画画了。而setNeedsLayout会默认调用layoutSubViews,就可以处理子视图中的一些数据。

综上所述:setNeedsDisplay方便绘图,而layoutSubViews方便出来数据

setNeedDisplay告知视图它发生了改变,需要重新绘制自身,就相当于刷新界面.

77.plist文件?结构是?

plist文件通常用于储存用户设置,也可以用于存储捆绑的信息,该功能在旧式的Mac OS中是由资源分支提供的。

plist主要有Core Fundation类型构成,也可以将这些类型放入NSDictionary和NSArray以便使用更复杂的数据类型

78.iOS里面的二进制数据类型是什么?和NSString如何互相转换?

NSData:用于存储二进制的数据类型

NSData类提供了一种简单的方式,它用来设置缓冲区、将文件的内容读入缓冲区,或将缓冲区的内容写到一个文件。

不变缓冲区(NSData类),也可定义可变的缓冲区(NSMutableData类)。

NSData、NSString互转:

NSData * data = [str dataUsingEncoding:NSUTF8StringEncoding];

//NSString转换成NSData类型

NSString * newStr = [[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding];

78. iOS里面的手势是如何实现的?

IOS开发中手势滑动的6种技巧

手势的种类
所有手势的父类:UIGestureRecognizer
6种手势:UI XXX GestureRecognizer
UITapGestureRecognizer  点击一下屏幕
UISwipeGestureRecognizer  轻扫屏幕,如解锁
UILongPressGestureRecognizer 长按手势
UIPinchGestureRecognizer  捏合手势
UIPanGestureRecognizer 移动手势
UIRotationGestureRecognizer 旋转手势

 如何使用手势
step1:创建手势对象
step2:设置与该手势相关的属性
step3:将手势对象与需要检测的视图关联在一起

79.谈谈你了解的设计模式,你用过哪些,他们的缺点

一、MVC:优点:
1、开发人员可以只关注整个结构中的其中某一层;

2、可以很容易的用新的实现来替换原有层次的实现;

3、可以降低层与层之间的依赖;

4、有利于标准化;

5、利于各层逻辑的复用。
缺点:

1、降低了系统的性能。这是不言而喻的。如果不采用分层式结构,很多业务可以直接造访数据库,以此获取相应的数据,如今却必须通过中间层来完成。

2、有时会导致级联的修改。这种修改尤其体现在自上而下的方向。如果在表示层中需要增加一个功能,为保证其设计符合分层式结构,可能需要在相应的业务逻辑层和数据访问层中都增加相应的代码。

二、观察者模式优点:
1、观察者模式在被观察者和观察者之间建立一个抽象的耦合。被观察者角色所知道的只是一个具体观察者列表,每一个具体观察者都符合一个抽象观察者的接口。被观察者并不认识任何一个具体观察者,它只知道它们都有一个共同的接口。

由于被观察者和观察者没有紧密地耦合在一起,因此它们可以属于不同的抽象化层次。如果被观察者和观察者都被扔到一起,那么这个对象必然跨越抽象化和具体化层次。

2、观察者模式支持广播通讯。被观察者会向所有的登记过的观察者发出通知,

观察者模式缺点:

1、如果一个被观察者对象有很多的直接和间接的观察者的话,将所有的观察者都通知到会花费很多时间。

2、如果在被观察者之间有循环依赖的话,被观察者会触发它们之间进行循环调用,导致系统崩溃。在使用观察者模式是要特别注意这一点。

3、如果对观察者的通知是通过另外的线程进行异步投递的话,系统必须保证投递是以自恰的方式进行的。

4、虽然观察者模式可以随时使观察者知道所观察的对象发生了变化,但是观察者模式没有相应的机制使观察者知道所观察的对象是怎么发生变化的。

三、单例模式
优点:

1、提供了对唯一实例的受控访问。

2、由于在系统内存中只存在一个对象,因此可以节约系统资源,对于一些需要频繁创建和销毁的对象单例模式无疑可以提高系统的性能。

3、允许可变数目的实例。

缺点:

1、由于单利模式中没有抽象层,因此单例类的扩展有很大的困难。

2、单例类的职责过重,在一定程度上违背了“单一职责原则”。

3、滥用单例将带来一些负面问题,如为了节省资源将数据库连接池对象设计为的单例类,可能会导致共享连接池对象的程序过多而出现连接池溢出;如果实例化的对象长时间不被利用,系统会认为是垃圾而被回收,这将导致对象状态的丢失.

80.数据持久化存储方案有哪些?

iOS中的数据持久化方式,基本上有以下四种:属性列表、对象归档、SQLite3和Core Data
1.属性列表(NSUserDefaults,用于存储配置信息)

涉及到的主要类:NSUserDefaults,一般[NSUserDefaults standardUserDefaults]就够用了

2.对象归档

要使用对象归档,对象必须实现NSCoding协议.大部分Object C对象都符合NSCoding协议,也可以在自定义对象中实现NSCoding协议,要实现NSCoding协议,实现两个方法

3.SQLite3

SQLite的数据库权限只依赖于文件系统,没有用户帐户的概念。SQLite有数据库级锁定,没有网络服务器。它需要的内存,其它开销很小,适合用于嵌入式设备。你需要做的仅仅是把它正确的编译到你的程序。

4.Core Data

Core Data本质上是使用SQLite保存数据,但是它不需要编写任何SQL语句。
要使用Core Data,需要在Xcode中的数据模型编辑器中设计好各个实体以及定义好他们的属性和关系。之后,通过操作这些对象,结合Core Data完成数据的持久化

81.网络通信用过哪些方式?

iOS设备的网络通信的方法,有如下两个大类:
1、使用socket的方式进行通信。

以TCP为利,对于TCP来说,是要区分服务端和客户端的。服务端:通常的方法是服务端启动后监听,是否有客户端连接,如果有连接,则建立与客户端的通信。客户端的方法通常是连接服务端,当连接成功之后,就希望发送数据了。

2、使用asynsocket类库进行通信。

82.如何处理多个网络请求并发的情况?

iOS面试题--网络--如何处理多个网络请求的并发的情况

1.并发当有多个线程在操作时,如果系统只有一个CPU,则它根本不可能真正同时进行一个以上的线程,它只能把CPU运行时间划分成若干个时间段,再将时间段分配给各个线程执行,在一个时间段的线程代码运行时,其它线程处于挂起状。.这种方式我们称之为并发(Concurrent)。

2.并行当系统有一个以上CPU时,则线程的操作有可能非并发。当一个CPU执行一个线程时,另一个CPU可以执行另一个线程,两个线程互不抢占CPU资源,可以同时进行,这种方式我们称之为并行(Parallel)。

3.区别并发和并行是即相似又有区别的两个概念,并行是指两个或者多个事件在同一时刻发生;而并发是指两个或多个事件在同一时间间隔内发生。

83.简单介绍一下KVC和KVO,他们都可以应用在哪些场景?

1.KVC:NSKeyValueCoding的简称,是一种可以直接通过字符串的名字(key)来访问类属性的机制,而不是通过调用的Setter、Getter方法访问。
KVC的操作方法由NSKeyValueCoding协议提供,NSObject就实现了这个协议,也就是说如果对象是NSObject的子对象那么就支持KVC操作,KVC有两种操作方法,一种是设值,一种是取值,可以理解为getter和setter,不过稍微有所不同的是,设置对象值的方法中有两个,setValue:属性值forKey:属性名(一般的设置,比如说是说设置NSString,NSNumber等基本类类型,setetValue:属性值forKeyPath:属性路径

2.KVO:NSKeyValueObserving的简称,当指定的对象的属性被修改了,允许对象接受到通知的机制。每次指定的被观察对象的属性被修改的时候,KVO都会自动的去通知相应的观察者,相当于设计模式中的观察者模式。

Key-Value Observing (KVO)建立在KVC之上,能够观察一个对象的KVC key path值的变化,接下来的做的实例是在iOS中视图的ViewDidLoad中实现的,跟KVC类似,不过可以监听值的变化,实现起来很简单addObserver添加观察,observeValueForKeyPath观察变化之后的事件,最后需要销毁以下监听事件,
即:添加监听-->观察监听-->销毁监听

84.实现多线程有哪些方法,分别有什么区别?

1.NSThread  2.NSOperationQueue   3.GCD
区别:

Thread是这三种范式里面相对轻量级的,但也是使用起来最负责的,你需要自己管理thread的生命周期,线程之间的同步。线程共享同一应用程序的部分内存空间,它们拥有对数据相同的访问权限。你得协调多个线程对同一数据的访问,一般做法是在访问之前加锁,这会导致一定的性能开销。在iOS中我们可以使用多种形式的thread:

Cocoa threads:使用NSThread或直接从NSObject的类方法performSelectorInBackground:withObject:来创建一个线程。如果你选择thread来实现多线程,那么NSThread就是官方推荐优先选用的方式。

Cocoa operations是基于Obective-C实现的,类NSOperation以面向对象的方式封装了用户需要执行的操作,我们只要聚焦于我们需要做的事情,而不必太操心线程的管理,同步等事情,因为NSOperation已经为我们封装了这些事情。NSOperation是一个抽象基类,我们必须使用它的子类。iOS提供了两种默认实现:NSInvocationOperation和NSBlockOperation。

Grand Central Dispatch (GCD): iOS4才开始支持,它提供了一些新的特性,以及运行库来支持多核并行编程,它的关注点更高:如何在多个cpu上提升效率。

85.iOS的/ OS X的图形是基于OpenGL。什么是OpenGL?

官方的解释:OpenGL是硬件基础图形加速在OS X的权力核心动画,核心形象,和石英的极端和给你的应用程序访问惊人的3D图形处理能力。使用工业标准的图形API创建一系列应用程序,包括游戏,动画制作软件,以及医疗成像解决方案。
OpenGL:(Open Graphics Library)是指定义了一个跨编程语言、跨平台的编程接口规格的专业的图形程序接口。它用于三维图像(二维的亦可),是一个功能强大,调用方便的底层图形库。计算机三维图形是指将用数据描述的三维空间通过计算转换成二维图像并显示或打印出来的技术。OpenGL就是支持这种转换的程序库,它源于SGI公司为其图形工作站开发的IRIS GL,在跨平台移植过程中发展成为OpenGL。OpenGL被设计成独立于硬件、独立于窗口系统,在各种操作系统的计算机上都可用的,并能在网络环境下以客户/服务器模式工作,是专业图形处理、科学计算等高端应用领域的标准图形库

86.什么是框架的CoreFoundation,什么是Foundation框架?

Core Foundation框架(CoreFoundation.framework)是一组C语言接口,它们为iOS应用程序提供基本数据管理和服务功能。

Foundation—基础框架。框架中包含了很多开发中常用的数据类型,如结构体,枚举,类等,是其他ios框架的基础。

如果要想使用foundation框架中的数据类型,那么包含它的主头文件就可以了。

即#import

补充:core foundation框架相对底层,里面的代码几乎都是c语言的,而foundation中是OC的。

87.你如何保存你的应用程序数据

XML属性列表-plist
偏好设置
归档

1.plist(XML属性列表归档)
2.偏好设置
3.NSKeydeArchiver归档(存储自定义对象)
4.SQLite3(数据库,关系型数据库,不能直接存储对象,要编写一些数据库的语句,将对象拆开存储)
5.Core Data(对象型的数据库,把内部环节屏蔽)

88.您是否使用Git版本控制?什么是合并和重订之间的区别?如果你没有使用Git,您使用的分布式版本控制系统?

附网址:什么是版本控制:https://git-scm.com/book/zh/ch1-1.html

国外网友的解释:http://translate.baiducontent.com/transpage?query=http%3A%2F%2Fserve.3ezy.com%2Fstackoverflow.com%2Fquestions%2F16666089%2Fwhats-the-difference-between-git-merge-and-git-rebase&from=en&to=zh&source=url

合订和重定的解释:http://translate.baiducontent.com/transpage?cb=translateCallback&ie=utf8&source=url&query=http%3A%2F%2Fserve.3ezy.com%2Fgit-scm.com%2Fbook%2Fen%2FGit-Branching-Rebasing&from=en&to=zh&token=&monLang=zh

视频的网址:http://www.git-tower.com/learn/git/videos/

89.Storyboard和Xib你喜欢哪个为什么?

xibs是XML文件定义和配置的一组对象,并专门操纵主要观点(UIView子类)。Xcode具有友好的编辑器,可以显示这些意见,它是一个运行的应用程序,使得它的配置和设计布局非常容易(节省很多行代码)。

即使大多数开发商关联一个xib文件“屏幕”或“视图控制器”,是通用的容器xibs对象和可以一起使用,与其它类型的对象作为nsobjectsUIViews,或者只是一个人。

Storyboard

这是一个XML文件代表统一一套xibs为了定义导航之间的一组视图控制器。有一个故事板一个开发者可以定义多个“屏幕”(或和导航之间的UIViewController类)他们。
作为一个差的XIB,故事是由定义的视图和导航处理他们之间。

xibs VS代码的好处

视图的可视化配置。

自动布局的视觉形态。

大小班的视觉形态。

节省时间和代码,而“创建实例”。

节省时间和代码,而“配置对象”。

快速UITableViewCell原型。

快速配置控制动作(ibactions)。

Storyboard与xibs效益

可以直接在脚本本身原型的行。

可以定义静态表格部分和行。

可以使用自动布局约束添加到toplayoutguide和bottomlayoutguide。

可以指定导航和过渡(这是一个主要的目的!)。

可以定义多个“屏幕”(处理的)在一个地方(不需要多xibs)。

对xibs VS代码不便

容易破裂合并时(GIT)。

不复杂的自动布局定义。

不能引用(或包括)其他xibs。

Storyboard与代码xibs不便

故事情节是:大文件的加载速度慢,有时。

需要一个大屏幕显示所有(或部分)的内容。

容易破裂合并时(GIT)。

高概率打破它时,合并(GIT)作为故事包含很多信息。

许多警告当支持iOS 7和iOS 8(利润,大小班)。

不能引用(或包括)其他xibs。

90.堆和栈的区别?

堆和栈的区别:

一、堆栈空间分配区别:

1、栈(操作系统):由操作系统自动分配释放,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构中的栈;

2、堆(操作系统):一般由程序员分配释放,若程序员不释放,程序结束时可能由OS回收,分配方式倒是类似于链表。

二、堆栈缓存方式区别:

1、栈使用的是一级缓存,他们通常都是被调用时处于存储空间中,调用完毕立即释放;

2、堆是存放在二级缓存中,生命周期由虚拟机的垃圾回收算法来决定(并不是一旦成为孤儿对象就能被回收)。所以调用这些对象的速度要相对来得低一些。

三、堆栈数据结构区别:

堆(数据结构):堆可以被看成是一棵树,如:堆排序;

栈(数据结构):一种先进后出的数据结构。

91.目标~动作机制

目标是动作消息的接收者。一个控件,或者更为常见的是它的单元,以插座变量(参见"插座变量"部分的形式保有其动作消息的目标。

动作是控件发送给目标的消息,或者从目标的角度看,它是目标为了响应动作而实现的方法。

程序需要某些机制来进行事件和指令的翻译。这个机制就是目标-动作机制

上一篇下一篇

猜你喜欢

热点阅读