iOS面试题

本文深入探讨iOS应用如何实现后台多任务处理,包括iOS版本更新带来的变化,如墓碑式冻结、真后台模式等。同时,文章详细讲解了iOS中的内存管理机制,包括自动内存计数(ARC)、手动内存计数、内存池等方法,以及如何正确使用`retain`、`copy`、`assign`等属性来管理对象生命周期。
摘要由CSDN通过智能技术生成

一.iOS应用是如何实现后台多任务处理(Multitasking)的?

 a. iOS4.0以前,后台只有推送功能;

 b.iOS4.0~7.0之前,“墓碑式”;(伪后台)

    在完成“墓碑式”冻结前最后的任务,就是从Active经由Inactive退到后台的时候,苹果官方允许5秒的时间通过调用-(void)applicationDidEnterBackground:方法处理。

 c.iOS7.0之后,真后台和服务,智能调度、

    后台服务常见的有:音乐播放和录制,例如打开虾米播放器再退到后台,音乐还是播放的

   定位服务,分为显著位置变化检测和高度精度的定位,后者支持定位跟踪;

   VoIP(Voice over Internet Protocol)简而言之就是将模拟信号(Voice)数字化

   蓝牙及外部设备通信。

 d.iOS7.0后新的东西

   三种:退到后台,短时间延续之前执行的任务。

          在前台时初始化,但尚未完成的下载任务,该功能主要通过NSURLSession这个类完成。

          新增后台运行的服务:

     fetch:在App的后台运行模式里选择fetch,系统会“智能”地调用ApplicationDelegate中的回调方法,实现上传或者下载任务.

          remote-notification:远端通知,即app不需要恢复前台状态,也可以对ApplicationDelegate的回调。

  1)程序退出。2)原生后台。3)真后台模式。4)自动选择模式。


二.请解释一下~/Documents,~/Library和~/tmp.iOS中的~属于什么目录?


    ~代表的是你当前用户的home目录;

    ~/Documents指的是苹果电脑当前用户的文稿文件夹;

    ~/Library 右键Finder ->前往文件夹 输入~/Library,就是资源库;

    ~/tmp — 打开Finder ->按shift+command+g,输入/tmp,就是tmp文件夹。

    


3.Swift和Objective-C分别是什么?两者相比有何不同之处,又有何联系?


4.你会选择什么工具来追踪Bug?

   Redmine 是一个开源的、基于Web的项目管理和缺陷跟踪工具。它用日历和甘特图辅助项目及进度可视化显示。同时它又支持多项目管理。Redmine是一个自由开放 源码软件解决方案,它提供集成的项目管理功能,问题跟踪,并为多个版本控制选项的支持。

   Redmine建立在Ruby on Rails的框架之上,支持跨平台和多种数据库。


5.iOS提供哪些线程?如何充分利用这些线程?

    有耗时操作的时候使用多线程,避免主线程堵塞。

方式:Pthread,NSThread,GCD,NSOperation.

Pthread:基于c语言底层库函数,使用起来比较麻烦,是面向过程编程。目前苹果官方基本上已经废弃。

NSThread:

     -优点:NSThread比其他(GCD\NSOperation)两个轻量级,使用简单。

     -缺点:需要自己管理线程的生命周期、线程同步、加锁、睡眠与及唤醒等。线程同步对数据的加锁会有一定的系统开销。

GCD:(Grand Central Dispatch)大中心调度,宏中心调度。

      -GCD是由苹果开发的一个多核编程的解决方案。iOS4.0+才能使用,是替代NSThread,NSOperation的高效和强大的技术。

      -基于c语言。

NSOperation:

     -不需要关心线程管理,数据同步的事情,可以把经历放在自己需要执行的操作上

     -NSOperation 是面向对象的。封装改进GCD。

       依赖、跨线程





1.Objc中,与alloc语义相反的方法是dealloc还是release?与retain语义相反的方法是dealloc还是release?为什么?需要与alloc配对使用的方法是dealloc还是release,为什么?

答:Objc中,与alloc语义相反的方法是dealloc,与retain语义相反的方法是release。alloc是为对象在内存中开辟空间,而dealloc则是对象销毁时释放空间。retain方法是对象开辟空间以后使对象的引用计数器加1,而release是对象的引用计数器减1.需要与alloc配对的方法是release,因为对象创建以后,对象的引用计数器自动加1,而调用release方法后,对象的引用计数器归0,系统会自动调用dealloc方法释放空间。


2.在一个对象的方法里面:self.name = @“object”;和 _name = @“object”有什么不同吗?

答:self.name = @“object”是通过”.”语法修改属性name的值,属性的本质是方法,系统会自动调用属性name的setter方法。_name = @“object”是直接修改成员变量_name的值,没有调用方法。


3.这段代码有什么问题吗?

   @implementation Person

-(void)setAge:(int)newAge{

self.age = newAge;

}

   @end

答:在属性的setter方法中,不能通过”.”语法给该属性赋值,会造成setter方法的循环调用。应该修改成_age = newAge;


4.以下每行代码执行后,person对象的retain count分别是多少?

   Person *person = [[Person alloc] init];

   [person retain];

   [person release];

   [person release];

答:第一行执行结束,person的retain count是1.第二行结束,retain count是2,第三行结束,retain count是1,第四行结束,person的retain count是0,person对象自动销毁。


5.这段代码有什么问题,如何修改?

   for(int i = 0; i < someLargeNumber; i++){

NSString *string = @“Abc”;

string = [string lowercaseString];

string = [string stringByAppendingString:@“xyz”];

NSLog(@“%@“, string);

   }

     

答:代码本身没有问题。如果是想在Abc后面拼接多个xyz字符串的话,需要把string的初始化放在循环语句外面。

放for里面屏幕快照 2015-12-23 下午5.08.09.png      放for外面屏幕快照 2015-12-23 下午5.07.50.png



6.简要叙述面向对象的特点,特别是多态。

答:

1、封装

封装是对象和类概念的主要特性。它是隐藏内部实现,稳定外部接口,可以看作是“包装”。 封装,也就是把客观事物封装成抽象的类,并且类可以把自己的数据和方法只让可信的类或者对象操作,对不可信的进行信息隐藏。

好处:使用更加简单  变量更加安全 可以隐藏内部实现细节  开发速度加快。

2、继承

面向对象编程 (OOP) 语言的一个主要功能就是“继承”。继承是指这样一种能力:它可以使用现有类的所有功能,并在无需重新编写原来的类的情况下对这些功能进行扩展。

通过继承创建的新类称为“子类”或“派生类”,被继承的类称为“基类”、“父类”或“超类”。继承的过程,就是从一般到特殊的过程。在考虑使用继承时,有一点需要注意,那就是两个类之间的关系应该是“属于”关系。例如,Employee 是一个人,Manager 也是一个人,因此这两个类都可以继承 Person 类。但是 Leg 类却不能继承 Person 类,因为腿并不是一个人。

3、多态

多态性(polymorphism)是允许你将父对象设置成为和一个或更多的他的子对象相等的技术,赋值之后,父对象就可以根据当前赋值给它的子对象的特性以不同的方式运作。简单的说,就是一句话:允许将子类类型的指针赋值给父类类型的指针。不同对象以自己的方式响应相同的消息的能力叫做多态。意思就是假设生物类(life)都用有一个相同的 方法-eat;那人类属于生物,猪也属于生物,都继承了life后,实现各自的eat,但是调用是我们只需调用各自的eat方法。也就是不同的对象以 自己的方式响应了相同的消息(响应了eat这个选择器)。

实现多态,有二种方式,覆盖,重载。

·    覆盖(override),是指子类重新定义父类的虚函数的做法。

·    重载(overload),是指允许存在多个同名函数,而这些函数的参数表不同(或许参数个数不同,或许参数类型不同,或许两者都不同)。

总结:封装可以隐藏实现细节,使得代码模块化;继承可以扩展已存在的代码模块(类);它们的目的都是为了——代码重用。而多态则是为了实现另一个目的——接口重用!多态的作用,就是为了类在继承和派生的时候,保证使用“家谱”中任一类的实例的某一属性时的正确调用。

在类层次中,子类只继承一个父类的数据结构和方法,则称为单重继承。 

在类层次中,子类继承了多个父类的数据结构和方法,则称为多重继承。 



7.objective-c 所有对象间的交互是如何实现的?

答:

在对象间交互中每个对象承担的角色不同,但总的来说无非就是”数据的发送者”或”数据的接收者”两种角色,我们可以通过代理去进行通信,或者通过观察者消息模式,blocks,appdelegagte

通过:代理协议”或者”通知中心”方式的实现能最大限度的降低两交互对象之间的耦合,不错的设计;


8.全局变量可不可以定义在被多个.c文件包含的头文件中?为什么?

答:

可以,在不同的c文件中以static 形式来声明同名全局变量。前提是其中只能有一个c文件中对此变量赋初值,此时连接不会出错。


9.如何引用一个已经定义过的全局变量?

答:extern

可以用引用头文件的方式,也可以用extern 关键字,如果用引用头文件的方式来引用某个在头文件中的全局变量,假定你那个变量写错了,那么编译期间会报错,如果用extern 方式引用时,假定你犯了同样的错误,那么在编译期间不会报错,而在连接期间报错。


10.什么叫数据结构?

答:数据结构是计算机存储、组织数据的方式。是指相互之间存在一种或多种特定关系的数据元素的集合。

通常,精心选择的数据结构可以带来更高的运行或者存储效率。


11.Sizeof和strlen的区别和联系?

答:Sizeof() 是运算符,可以用类型做参数,还可以用函数做参数,功能是获得保证能容纳实现所建立的最大对象的字节大小;

strlen()是函数,要在运行时才能计算。参数必须是字符行指针且必须是以”\0″结尾的。功能为:返回字符串的的长度。


12.OC的类可以多继承吗?可以实现多个接口吗?Category是什么?分类中能定义成员变量或属性吗?为什么?重写一个类的方式是继承好还是分类好?为什么?

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


13.#import和#include有什么区别?@class呢?#import<>和#import” ”有什么区别?

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


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

答:

1.readwrite 是可读可写特性;需要生成getter方法和setter方法时(补充:默认属性,将生成不带额外参数的getter和setter方法(setter方法只有一个参数))

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

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

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

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

6.nonatomic 非原子操作,决定编译器生成的setter getter是否是原子操作,atomic表示多线程安全,一般使用nonatomic


15.写一个setter方法用于完成@property(nonatomic, retain)NSString *name, 写一个setter方法用于完成@property(nonatomic, copy)NSString *name

答:

- (void) setName:(NSString*) str

 {

  [str retain];

  [name release];

  name = str;

 }

- (void)setName:(NSString *)str

 {

  id t = [str copy];

  [name release];

  name = t;

 }


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

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


17.常见的OC的数据类型有哪些? 和C的基本数据类型有什么区别? 如:NSInteger和int

答:

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


18.id声明的对象有什么特性?

答:

Id 声明的对象具有运行时的特性,即可以指向任意类型的objcetive-c的对象;


19.OC如何对内存管理的,说说你的看法和解决方法。

答:

Objective-C的内存管理主要有三种方式ARC(自动内存计数)、手动内存计数、内存池。

  1. (Garbage Collection)自动内存计数:这种方式和java类似,在你的程序的执行过程中。始终有一个高人在背后准确地帮你收拾垃圾,你不用考虑它什么时候开始工作,怎样工作。你只需要明白,我申请了一段内存空间,当我不再使用从而这段内存成为垃圾的时候,我就彻底的把它忘记掉,反正那个高人会帮我收拾垃圾。遗憾的是,那个高人需要消耗一定的资源,在携带设备里面,资源是紧俏商品所以iPhone不支持这个功能。所以“Garbage Collection”不是本入门指南的范围,对“Garbage Collection”内部机制感兴趣的同学可以参考一些其他的资料,不过说老实话“Garbage Collection”不大适合适初学者研究。

  解决: 通过alloc – initial方式创建的, 创建后引用计数+1, 此后每retain一次引用计数+1, 那么在程序中做相应次数的release就好了.

  2. (Reference Counted)手动内存计数:就是说,从一段内存被申请之后,就存在一个变量用于保存这段内存被使用的次数,我们暂时把它称为计数器,当计数器变为0的时候,那么就是释放这段内存的时候。比如说,当在程序A里面一段内存被成功申请完成之后,那么这个计数器就从0变成1(我们把这个过程叫做alloc),然后程序B也需要使用这个内存,那么计数器就从1变成了2(我们把这个过程叫做retain)。紧接着程序A不再需要这段内存了,那么程序A就把这个计数器减1(我们把这个过程叫做release);程序B也不再需要这段内存的时候,那么也把计数器减1(这个过程还是release)。当系统(也就是Foundation)发现这个计数器变成了0,那么就会调用内存回收程序把这段内存回收(我们把这个过程叫做dealloc)。顺便提一句,如果没有Foundation,那么维护计数器,释放内存等等工作需要你手工来完成。

  解决:一般是由类的静态方法创建的, 函数名中不会出现alloc或init字样, 如[NSString string]和[NSArray arrayWithObject:], 创建后引用计数+0, 在函数出栈后释放, 即相当于一个栈上的局部变量. 当然也可以通过retain延长对象的生存期.

  3. (NSAutoRealeasePool)内存池:可以通过创建和释放内存池控制内存申请和回收的时机.

  解决:是由autorelease加入系统内存池, 内存池是可以嵌套的, 每个内存池都需要有一个创建释放对, 就像main函数中写的一样. 使用也很简单, 比如[[[NSString alloc]initialWithFormat:@”Hey you!”] autorelease], 即将一个NSString对象加入到最内层的系统内存池, 当我们释放这个内存池时, 其中的对象都会被释放


20.你对@interface和@property的理解

答:

1. 只在@interface中定义变量的话,你所定义的变量只能在当前的类中访问,在其他类中是访问不了的;而用@property声明的变量可以在外部访问。

2.用了@property去声明的变量,可以使用“self.变量名”的方式去读写变量。而用@interface的方式就不可以。


21.调用一个类的静态方法需不需要release?

答:一般情况不需要release,因为静态方法不需要对象,不需要release;


I22.do while 和while do的区别?

答:第一个是先进行判断在在执行循环。do while先进行循环一次再进行循环语句;


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

答:#define SECONDS_PER_YEAR (60 * 60 * 24 * 365)UL


24.Difference between shallow copy and deep copy?

浅复制和深复制的区别?

答案:浅层复制:只复制指向对象的指针,而不复制引用对象本身。

  深层复制:复制引用对象本身。

意思就是说我有个A对象,复制一份后得到A_copy对象后,对于浅复制来说,A和A_copy指向的是同一个内存资源,复制的只不过是是一个指针,对象本身资源还是只有一份,那如果我们对A_copy执行了修改操作,那么发现A引用的对象同样被修改,这其实违背了我们复制拷贝的一个思想。深复制就好理解了,内存中存在了两份独立对象本身。

用网上一哥们通俗的话将就是:

浅复制好比你和你的影子,你完蛋,你的影子也完蛋

深复制好比你和你的克隆人,你完蛋,你的克隆人还活着。


1.浅复制与深复制的区别?

答:简单的来说就是,在有指针的情况下,浅拷贝只是增加了一个指针指向已经存在的内存,对其中任何一个对象的改动都会影响另外一个对象。而深拷贝就是增加一个指针并且申请一个新的内存,使这个增加的指针指向这个新的内存,采用深拷贝的情况下,释放内存的时候就不会出现在浅拷贝时重复释放同一内存的错误,其中任何一个对象的改动都不会对另外一个对象造成影响。

用网上一哥们通俗的话将就是:
浅复制好比你和你的影子,你完蛋,你的影子也完蛋
深复制好比你和你的克隆人,你完蛋,你的克隆人还活着

23Difference between shallow copy and deep copy?浅复制和深复制的区别?答案:浅层复制:只复制指向对象的指针,而不复制引用对象本身。深层复制:复制引用对象本身。意思就是说我有个A对象,复制一份后得到A_copy对象后,对于浅复制来说,A和A_copy指向的是同一个内存资源,复制的只不过是是一个指针,对象本身资源还是只有一份,那如果我们对A_copy执行了修改操作,那么发现A引用的对象同样被修改,这其实违背了我们复制拷贝的一个思想。深复制就好理解了,内存中存在了两份独立对象本身。用网上一哥们通俗的话将就是:浅复制好比你和你的影子,你完蛋,你的影子也完蛋深复制好比你和你的克隆人,你完蛋,你的克隆人还活着。



25.What is advantage of categories? What is difference between implementing a category and inheritance?

类别的作用?继承和类别在实现中有何区别?

答案:category 可以在不获悉,不改变原来代码的情况下往里面添加新的方法,只能添加,不能删除修改。并且如果类别和原来类中的方法产生名称冲突,则类别将覆盖原来的方法,因为类别具有更高的优先级。

类别主要有3个作用:

(1)将类的实现分散到多个不同文件或多个不同框架中。

(2)创建对私有方法的前向引用。

(3)向对象添加非正式协议。 继承可以增加,修改或者删除方法,并且可以增加属性。


26.Difference between categories and extensions?类别和类扩展的区别。

答案:category和extensions的不同在于 后者可以添加属性。另外后者添加的方法是必须要实现的。extensions可以认为是一个私有的Category。


27.Difference between protocol in objective c and interfaces in java?

oc中的协议和java中的接口概念有何不同?

答案:OC中的代理有2层含义,官方定义为 formal和informal protocol。前者和Java接口一样。informal protocol中的方法属于设计模式考虑范畴,不是必须实现的,但是如果有实现,就会改变类的属性。其实关于正式协议,类别和非正式协议我很早前学习的时候大致看过,也写在了学习教程里“非正式协议概念其实就是类别的另一种表达方式“这里有一些你可能希望实现的方法,你可以使用他们更好的完成工作”。这个意思是,这些是可选的。比如我门要一个更好的方法,我们就会申明一个这样的类别去实现。然后你在后期可以直接使用这些更好的方法。这么看,总觉得类别这玩意儿有点像协议的可选协议。"现在来看,其实protocal已经开始对两者都统一和规范起来操作,因为资料中说“非正式协议使用interface修饰“,现在我们看到协议中两个修饰词:“必须实现(@requied)”和“可选实现(@optional)”。


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



1.如何将产品进行多语言发布,开发?

答:

一是程序支持多语言,用到的技术点有xib分化成多语言,还有就是动态取本地字符串.

二是发布的时候,要多选几个国家, 这样就可以完成多语言了.


2.OC中是如何实现线程同步的?

答:Mutexlock (互斥锁)、NSCondition lock (条件锁)消息传送


3.UDP和TCP的区别是什么?

答:

1.基于连接与无连接;

2.对系统资源的要求(TCP较多,UDP少);

3.UDP程序结构较简单;

4.流模式与数据报模式 ;

5.TCP保证数据正确性,UDP可能丢包,TCP保证数据顺序,UDP不保证


4.TCP/IP建立连接的过程?

答:

在TCP/IP 协议中,TCP协议提供可靠的连接服务,采用三次握手建立连接;

第一次握手:建立连接时,客户端发送连接请求到服务器,并进入SYN_SEND状态,等待服务器确认;

第二次握手:服务器收到客户端连接请求,向客户端发送允许连接应答,此时服务器进入SYN_RECV状态;

第三次握手:客户端收到服务器的允许连接应答,向服务器发送确认,客户端和服务器进入通信状态,完成三次握手。

(所谓的三次握手,就是要有三次连接信息的发送、接收过程。TCP连的建立需要进行三次连接信息的发送、接收。)


5.编程中,保存数据有哪几种方式?

答:数组、自定义类、文件操作,数据库:如(SQLite 、core data、 plist 、NSUserDefaults、file )—持久保存数据


6.介绍版本控制中git方式与SVN。

答:

1、Git是一款免费、开源的分布式版本控制系统,用于敏捷高效地处理任何或小或大的项目。

2、SVN是Subversion的简称,是一个开放源代码的版本控制系统,它采用了分支管理系统,它的设计目标就是取代CVS。


7.OC中创建线程的方法是什么?如果在主线程中执行代码,方法是什么?如果想延时执行代码,方法又是什么?

答:

线程创建有三种方法:使用NSThread创建、使用GCD的dispatch、使用子类化的NSOperation,然后将其加入NSOperationQueue;在主线程执行代码,方法是performSelectorOnMainThread,如果想延时执行代码可以用performSelector:onThread:withObject:waitUntilDone:


8.iOS中有哪些多线程方案?

答:常用的有三种: NSThread NSOperationQueue GCD。

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

2、NSOperationQueue 以面向对象的方式封装了用户需要执行的操作,我们只要聚焦于我们需要做的事情,而不必太操心线程的管理,同步等事情,因为NSOperation已经为我 们封装了这些事情。 NSOperation 是一个抽象基类,我们必须使用它的子类。

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


9.NSOperation queue?答案:存放NSOperation的集合类。操作和操作队列,基本可以看成java中的线程和线程池的概念。用于处理ios多线程开发的问题。网上部分资料提到一点是,虽然是queue,但是却并不是带有队列的概念,放入的操作并非是按照严格的先进现出。这边又有个疑点是,对于队列来说,先进先出的概念是Afunc添加进队列,Bfunc紧跟着也进入队列,Afunc先执行这个是必然的,但是Bfunc是等Afunc完全操作完以后,B才开始启动并且执行,因此队列的概念离乱上有点违背了多线程处理这个概念。但是转念一想其实可以参考银行的取票和叫号系统。因此对于A比B先排队取票但是B率先执行完操作,我们亦然可以感性认为这还是一个队列。但是后来看到一票关于这操作队列话题的文章,其中有一句提到“因为两个操作提交的时间间隔很近,线程池中的线程,谁先启动是不定的。”瞬间觉得这个queue名字有点忽悠人了,还不如pool~综合一点,我们知道他可以比较大的用处在于可以帮组多线程编程就好了。


10. 线程与进程的区别和联系?答案: 进程和线程都是由操作系统所体会的程序运行的基本 单元,系统利用该基本单元实现系统对应用的并发性。程和线程的主要差别在于它们是不同的操作系统资源 管理方式。进程有独立的地址空间,一个进程崩溃后,在保护模式下不会对其它进程产生影响,而线程只是一个进程中的不同执行路径。线程有自己的堆栈和局部变 量,但线程之间没有单独的地址空间,一个线程死掉就等于整个进程死掉,所以多进程的程序要比多线程的程序健壮,但在进程切换时,耗费资源较大,效率要差一 些。但对于一些要求同时进行并且又要共享某些变量的并发操作,只能用线程,不能用进程。


11.ios平台怎么做数据的持久化?coredata和SQLite有无必然联系?coredata是一个关系型数据库吗?iOS中可以有四种持久化数据的方式: 属性列表、对象归档、SQLite3和Core Data;core data可以使你以图形界面的方式快速的定义app的数据模型,同时在你的代码中容易获取到它。core data提供了基础结构去处理常用的功能,例如保存,恢复,撤销和重做,允许你在app中继续创建新的任务。在使用core data的时候,你不用安装额外的数据库系统,因为core data使用内置的sqlite数据库。core data将你app的模型层放入到一组定义在内存中的数据对象。core data会追踪这些对象的改变,同时可以根据需要做相反的改变,例如用户执行撤销命令。当core data在对你app数据的改变进行保存的时候,core data会把这些数据归档,并永久性保存。mac os x中sqlite库,它是一个轻量级功能强大的关系数据引擎,也很容易嵌入到应用程序。可以在多个平台使用,sqlite是一个轻量级的嵌入式sql数据库编程。与core data框架不同的是,sqlite是使用程序式的,sql的主要的API来直接操作数据表。Core Data不是一个关系型数据库,也不是关系型数据库管理系统(RDBMS)。虽然Core Dta支持SQLite作为一种存储类型,但它不能使用任意的SQLite数据库。Core Data在使用的过程种自己创建这个数据库。Core Data支持对一、对多的关系。






2.列举下iOS常见的UI控件有哪些?(不得少于6个)

 UISegmentControl (分段控制器)、UISlider(滑块)、UISwitch(开关) 、UIActivityIndicatorView(加载指示器)、UIProgressView(进度条)、UIStepper(步控件)、UITextView (文本输入)、UILabel (显示信息)、UIButton(按钮)、UITouch(触摸)、UITextField、UINavigationController(导航控制器)、UIToolbar、UIImageView(视图)、UISearch Bar(搜索按钮)、UIActionSheet(实现硬编码按钮)、UIAlertView、UITabBarController 、UIPickerView、UIControl (创建用户界面控件对象) 、UIDatePicker (日期/时间选取器) 、UIScrollView、UITableView、UIPageControl (用来控制翻页)。




3.frame和bounds有什么不同?

答:位置和大小由对象的属性frame决定,frame属性是一个CGRect类型的结构体, 这个结构体由4个值决定,可以用函数CGRectMake来创建这个结构体。

  frame指的是:该view在父view坐标系统中的位置和大小。(参照点是父亲的坐标系统)//frame:框架、结构bounds指的是:该view在本身坐标系统中的位置和大小。(参照点 是本身坐标系统) //bounds:界限




4.#import、#include 与及 #class 有什么区别?

  答:@class一般用于头文件中需要声明该类的某个实例变量的时候用到,在m文 件中还是需要使用#import 

      而#import比起#include的好处就是不会引起交叉编译


5.在一个对象的方法里面:self.name = “object” 和 name = “object”,有什么不同吗?


答: self.name =”object”:会调用对象的setName()方法;

    name = “object”:会直接把object赋值给当前对象的name属性。



6.列举下你常用的cocoa touch框架。

 Map Kit 框架\UIKit 框架\Foundation和Core Data框架\

  C 语言 API 来直接访问系统:

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

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

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


7.定义属性时,什么情况使用copy,weak,strong,assign,和retain?



8.什么是多重继承?Objective-C有多重继承吗?如果没有,有什么替代方法?

  cocoa 中所有的类都是NSObject 的子类,多继承在这里是用protocol 委托代理来实现的。你不用去考虑繁琐的多继承,虚基类的概念。多态特性在 obj-c 中通过委托来实现。


9.用Objective-C语言实现下冒泡排序算法。

-(void)sort:(NSMutableArray *)arr

{

  for(int i = 0;i<arr.count;i++){

       for(int j = 0;j<arr.count-i-1;j++){

      if([arr[j+1]integerValue]<[arr[j] integerValue]){

         int temp = [arr[j] integerValue];

          arr[j] = arr[j+1];

          arr[j+1] = [NSNumber numberWithInt:temp];

       }

}

  }

}

 NSLog(@“毛破排序后:%@“,arr);

}


I

10.堆和栈的区别。

 堆和栈的区别:

  一、堆栈空间分配区别:

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

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

  二、堆栈缓存方式区别:

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

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

  三、堆栈数据结构区别:

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

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


11.简述下 iOS的内存管理机制。

 如果您通过分配和初始化(比如[[MyClassalloc]init])的方式来创建对象,您就拥有这个对象,需要负责该对象的释放。这个规则在使用NSObject的便利方法new时也同样适用。

 

如果您拷贝一个对象,您也拥有拷贝得到的对象,需要负责该对象的释放。 如果您保持一个对象,您就部分拥有这个对象,需要在不再使用时释放该对象。 反过来,如果您从其它对象那里接收到一个对象,则您不拥有该对象,也不应该释放它(这个规则有少数的例外,在参考文档中有显式的说明)。


12.谈谈你对MVC的认识与理解。



13. readwrite,readonly,assign,retain,copy,nonatomic 属性的作用

    @property是 一个属性访问声明,扩号内支持以下几个属性:

    1,getter=getName,setter=setName,设置setter与 getter的方法名

    2,readwrite,readonly,设置可供访问级别

    3.assign,setter方法直接赋值,不进行任何retain操作,为了解决原类型与环循引用问题

    4.retain,setter方法对参数进行release旧值再retain新值,所有 实现都是这个顺序(CC上有相关资料)

    5.copy,setter方法进行Copy操作,与retain处理流程一样,先旧值release,再 Copy出新的对象,retainCount为1。这是为了减少对上下文的依赖而引入的机制。

    6.nonatomic,非原子性访问,不加同步, 多线程并发访问会提高性能。注意,如果不加此属性,则默认是两个访问方法都为原子型事务访问。锁被加到所属对象实例级。


14.队列和栈有什么区别:

 答:队列和栈是两种不同的数据容器。从”数据结构”的角度看,它们都是线性结构,即数据元素之间的关系相同。

    队列是一种先进先出的数据结构,它在两端进行操作,一端进行入队列操作,一端进行出列队操作。 

    栈是一种先进后出的数据结构,它只能在栈顶进行操作,入栈和出栈都在栈顶操作。


15.列举一下你使用过的第三方框架.

GDataXML(google)、SDWebImage、AFNetworking.



17什么是KVC和KVO?

答:KVC(Key-Value-Coding)内部的实现:一个对象在调用setValue的时候,

(1)首先根据方法名找到运行方法的时候所需要的环境参数。

(2)他会从自己isa指针结合环境参数,找到具体的方法实现的接口。

(3)再直接查找得来的具体的方法实现。

KVO(Key-Value- Observing):当观察者为一个对象的属性进行了注册,被观察对象的isa指针被修改的时候,isa指针就会指向一个中间类,而不是真实的类。所以 isa指针其实不需要指向实例对象真实的类。所以我们的程序最好不要依赖于isa指针。在调用类的方法的时候,最好要明确对象实例的类名


copy与retain:

1、copy其实是建立了一个相同的对象,而retain不是;

2、copy是内容拷贝,retain是指针拷贝;  

3、copy是内容的拷贝 ,对于像NSString,的确是这样,但是如果copy的是一个NSArray呢?这时只是copy了指向array中相对应元素的指针.这便是所谓的"浅复制".

4、copy的情况:NSString *newPt = [pt copy];

此时会在堆上重新开辟一段内存存放@"abc" 比如0X1122 内容为@"abc 同时会在栈上为newPt分配空间 比如地址:0Xaacc 内容为0X1122 因此retainCount增加1供newPt来管理0X1122这段内存;


assign与retain:

1、assign: 简单赋值,不更改索引计数;

2、assign的情况:NSString *newPt = [pt assing]; 

此时newPt和pt完全相同 地址都是0Xaaaa 内容为0X1111 即newPt只是pt的别名,对任何一个操作就等于对另一个操作, 因此retainCount不需要增加;

3、assign就是直接赋值;

4、retain使用了引用计数,retain引起引用计数加1, release引起引用计数减1,当引用计数为0时,dealloc函数被调用,内存被回收;    

5、retain的情况:NSString *newPt = [pt retain]; 

此时newPt的地址不再为0Xaaaa,可能为0Xaabb 但是内容依然为0X1111。 因此newPt 和 pt 都可以管理"abc"所在的内存,因此 retainCount需要增加1 ;


readonly:

1、属性是只读的,默认的标记是读写,如果你指定了只读,在@implementation中只需要一个读取器。或者如果你使用@synthesize关键字,也是有读取器方法被解析 

 

readwrite:

1、说明属性会被当成读写的,这也是默认属性。设置器和读取器都需要在@implementation中实现。如果使用@synthesize关键字,读取器和设置器都会被解析;


nonatomic:

1、非原子性访问,对属性赋值的时候不加锁,多线程并发访问会提高性能。如果不加此属性,则默认是两个访问方法都为原子型事务访问;




15.readwritereadonlyassignretaincopynonatomic属性的作用 

@property是一个属性访问声明,扩号内支持以下几个属性: 

1,getter=getterName,setter=setterName,设置setter与getter的方法名 

2,readwrite,readonly,设置可供访问级别 

2,assign,setter方法直接赋值,不进行任何retain操作,为了解决原类型与环循引用问题 

3,retain,setter方法对参数进行release旧值再retain新值,所有实现都是这个顺序(CC上有相关资料) 

4,copy,setter方法进行Copy操作,与retain处理流程一样,先旧值release,再Copy出新的对象,retainCount为1。这是为了减少对上下文的依赖而引入的机制。 

copy是在你不希望a和b共享一块内存时会使用到。a和b各自有自己的内存。

5,nonatomic,非原子性访问,不加同步,多线程并发访问会提高性能。注意,如果不加此属性,则默认是两个访问方法都为原子型事务访问。锁被加到所属对象实例级(我是这么理解的...)。

atomic和nonatomic用来决定编译器生成的getter和setter是否为原子操作。在多线程环境下,原子操作是必要的,否则有可能引起错 误的结果




27What is purpose of delegates?

代理的作用?

答案:代理的目的是改变或传递控制链。允许一个类在某些特定时刻通知到其他类,而不需要获取到那些类的指针。可以减少框架复杂度。另外一点,代理可以理解为java中的回调监听机制的一种类似。


30what is difference between NSNotification and protocol?

通知和协议的不同之处?

答案:协议有控制链(has-a)的关系,通知没有。首先我一开始也不太明白,什么叫控制链(专业术语了~)。但是简单分析下通知和代理的行为模式,我们大致可以有自己的理解简单来说,通知的话,它可以一对多,一条消息可以发送给多个消息接受者。代理按我们的理解,到不是直接说不能一对多,比如我们知道的明星经济代理人,很多时候一个经济人负责好几个明星的事务。只是对于不同明星间,代理的事物对象都是不一样的,一一对应,不可能说明天要处理A明星要一个发布会,代理人发出处理发布会的消息后,别称B的发布会了。但是通知就不一样,他只关心发出通知,而不关心多少接收到感兴趣要处理。因此控制链(has-a从英语单词大致可以看出,单一拥有和可控制的对应关系。


31What is push notification?

什么是推送消息?

答案:太简单,不作答~~~~~~~~~~这是cocoa上的答案。

其实到不是说太简单,只是太泛泛的一个概念的东西。就好比说,什么是人。推送通知更是一种技术。简单点就是客户端获取资源的一种手段。普通情况下,都是客户端主动的pull。推送则是服务器端主动push。


37What is lazy loading?

答案:懒汉模式,只在用到的时候才去初始化。也可以理解成延时加载。我觉得最好也最简单的一个列子就是tableView中图片的加载显示了。一个延时载,避免内存过高,一个异步加载,避免线程堵塞。



58堆和栈上的指针 

指针所指向的这块内存是在哪里分配的,在堆上称为堆上的指针,在栈上为栈上的指针. 

在堆上的指针,可以保存在全局数据结构中,供不同函数使用访问同一块内存. 

在栈上的指针,在函数退出后,该内存即不可访问.


59什么是指针的释放? 

具体来说包括两个概念. 

1 释放该指针指向的内存,只有堆上的内存才需要我们手工释放,栈上不需要. 

2 将该指针重定向为NULL. 


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值