iOS初级工程师OC面试题

本文详细介绍了iOS开发中Objective-C的基本特点,包括OC与Java的单继承区别、id类型、switch语句的使用以及与if语句的比较。还探讨了内存管理、协议、分类、内存管理原则、深浅复制、堆栈区别等关键概念,并通过面试题形式讲解了retain count、ARC技术、拷贝实现、属性修饰符、KVC与KVO、自动释放池等知识点,帮助iOS初级工程师准备面试。
摘要由CSDN通过智能技术生成

1、OC语言的基本特点

(1)OC语言是C语言的一个超集,只有在C的基础上加上了面向对象的特点;

(2)OC与Java语言相同都是单继承,这一点与C++语言不同,C++语言是多继承;

(3)OC不支持命名空间机制,取而代之的是在类名之前添加前缀。

2、解释id类型

(1)OC的数据类型可以分为基本数据类型、对象类型和id类型;

(2)id可以指向任意OC对象类型,程序运行时才决定对象的类型。

3、switch语句每一句case都需要添加break语句吗?

switch语句中的break语句不是必须的,此外,default语句也不是必须添加的,如果在某一个条件case语句之后添加break语句,即当条件满足时,跳出switch语句。

4、switch语句和if语句区别与联系以及它的优势在哪里?

  都表示条件的判断,switch语句表达式只能处理整型,字符型和枚举型,if语句没有这样的限制。但是switch语句比if语句(选择流程控制语句)效率更高。

5、break和continue的区别?

  (1)break是结束整个循环体;

  (2)continue是结束本次循环。

  (3)break之后不再循环,continue结束本次循环后,再开始下一次的循环。

  (4)continue语句只是结束本次的循环,而不是终止整个的执行,接着进行下一次是否执行循环的判定。 
  (5)而break语句则是结束整个循环过程,不再判断执行循环的条件是否成立。
6、do while语句和while语句的区别,并写出几个死循环。
  (1)do while语句至少执行一次循环体,而while语句括号中表达式为真,才执行循环体。
  (2)while(1){}、for(;;)、for(int i=0;;i++)
7、int number = 26 , k = 1 , 求k的值
  do{
      k*=number%10;
      number/= 10;
}while(number);

  do while 语句的特点是循环体至少执行一次。程序执行到表达式 k*=number%10,已知number 为 26,又已知算术运算符比赋值运算符好优先级别高,因此先计算 number%10,其结果为 6 ;已知 k 为 1,因此 k 的结果为 6。number/=10 ,number 的值2。while 语句判断表达式是否为真,此时 number 为 2。继续执行循环体,此时 number、k 的值分别为 2、6,2%10 的结果仍为 2 ,再与 k 相乘,其 k 的结果为 12。程序执行到循环体第二行 number/10,此 时 number 已为 10,因此,number 的结果为 0。while 表达式内条件为假,循 环就此结束。因此,k 的值为 12。

 

8、#include与#import的区别,#import 与@class 的区别

  #include 和 #import 其效果相同,都是查询类中定义的行为(方法)。只是后者不会引起交叉编译,确保头文件只会被导入一次。@class 只定义了类的名称,而具体类的行为是不知道,,一般用于.h 文件,因此,@class 比#import 编译效率更高。此外 @class 和 #import 的主要区别在于解决引用死锁的问题。

 

9、@public、@protected、@private它们的含义与作用

  (1) @public:对象的实例变量的作用域在任意地方都可以被访问

  (2) @protected:对象的实例变量作用域在本类和子类都可以被访问

  (3) @private: 实例变量的作用域只能在本类(自身)中访问

 

10、通过指针运算符(->)能够访问到 private 方法吗? OC语言中还提供了哪些方式能直接和间接的访问对象的实例变量?

  不可以,可以通过合成存取器访问实例变量,也可自己定义 setter 和 getter 方法访问实例变量,KVC(key value coding)——键值编码,间接的方式访问实例变量。

 

11、协议(代理)的基本概念和协议(代理)中方法默认为什么类型?

  OC中的协议是一个方法列表。它的特点是可以被任何类使用(实现),但它并不是类(这里我们需要注意),自身不会实现这样方法, 但是又被其他类来实现。协议经常用来实现委托对象(委托设计模式)。 如果一个类采用了一个协议,那么它必须实现协议中必须需要实现的方法,在协议中的方法默认是必须实现(@required),添加关键字@optional,表示这些“可选”的方法是可以选择不实现的。

 

12、简述类目(分类)优点和缺点,如果覆盖本类或者父类的方法,会出现什么问题?

  (1)优点:不需要通过增加子类而增加现有类的行为(方法),且类目中的方法与原始类方法基本没有区别,通过类目可以将庞大一个类的方法进行划分,从而便于代码的日后的维护、更新以及提高代码的阅读性。

  (2)缺点:无法向类目添加实例变量,如果需要添加实例变量,只能通过定义子类的方式,类目中的方法与原始类以及父类方法相比具有更高级别的优先级,如果覆盖父类的方法,可能导致 super 消息的断裂,因此最好不要覆盖原始类中的方法。

 

13、简述内存管理基本原则

  (1)如果使用 alloc、copy(mutableCopy)或者retian 一个对象时,你就有义务,向它发送一 release 或者 autorelease 消息。其他方法创建的对象,不需要由你来管理内存。

  (2)向一个对象发送一条 autorelease 消息,这个对象并不会立即销毁, 而是将这个对象放入了自动释放池,待池子释放时,它会向池中每一个对象发送 一条 release 消息,以此来释放对象。

  (3)向一个对象发送 release 消息,并不意味着这个对象被销毁了,而是当这个对象的引用计数为 0 时,系统才会调用 dealloc 方法,释放该对象和对象本身它所拥有的实例。

 

 

14、在OC中是否支持垃圾回收机制?

  OC是支持垃圾回收机制的(Garbage collection简称GC),但是apple的 移动终端中,是不支持GC的,Mac 桌面系统开发中是支持的。

 

15、什么是 ARC 技术?与 GC 是否相同?

  ARC 是 Automatic Reference Counting 的简称,我们称之为自动引用计数, 是在iOS 5之后推出的新技术,它与GC的机制是不同的。我们在编写代码时, 不需要向对象发送 release 或者 autorelease 方法,也不用调用 dealloc 方法, 编译器会在合适的位置自动给用户生成 release 消息(autorelease),ARC 的特点是自动引用技术简化了内存管理的难度。

 

16、什么是 retain count

  每一个对象都默认有一个 retainCount 的属性,数值的多少表示现在有几个实例正在引用它。当它为 0 时,系统会自动调用 dealloc 方法,将内存回收。

 

 

17、深、浅复制的基本概念以及他们的区别。

  浅复制:只复制对象本身,不对里面的属性复制。

  深复制:不仅复制对象本身,对象持有的属性对象也做复制。

 

 

 

18、堆和栈的区别

  (1)栈区(stack): 由编译器自动分配释放,存放方法(函数)的参数值, 局部变量的值等,先进后出。

  (2)堆区(heap): 一般由程序员分配释放, 若程序员不释放,程序结束时由OS回收。

  (3)全局区(静态区)(static):全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域, 未初始化的全局变量和未初始化的静态变量在相邻的另一块区域。程序结束后有系统释放。

  (4)文字常量区: 常量字符串就是放在这里的。程序结束后由系统释放。 (5)程序代码区—存放函数体的二进制代码。

 

 

 

 

19、用户自定义了一个对象,如何实现拷贝(可变和不可变拷贝)

答:必须实现 copying 和 mutableCopying 协议,表示返回一个不可变和可变的对象。否则程序将会出现异常。

-(id)copyWithZone:(NSZone *)zone

{

Person *person =[[self Class] allocWithZone:zone]; person ->age = self.age;

person ->name =self.name;

return person;

}

-(id)mutableCopyWithZone(NSZone *)zone;

 

20、以下代码有问题吗?如果有,会出现什么问题

- (void)setName:(NSString *)name {

 

self.name = name;

 

}

答:引起重复调用(自己调用自己)。

 

 

21、定义属性时,什么时候用 assign、retain、copy 以及它们的之间的区别

答:(1)assign:普通赋值,一般常用于基本数据类型,常见委托设计模式, 以此来防止循环引用。(我们称之为弱引用,weak)

(2)retain:保留计数,获得到了对象的所有权。引用计数在原有基础上加1。

(3)copy:一般认为,是在内存中重新开辟了一个新的内存空间,用来存储新的对象,和原来的对象是两个不同的地址,引用计数分别 1。但是当 copy 对象为不可变对象时,那么 copy 的作用相当于 retain。因为,这样可以节约内存空间。

 

 

22、解释以下关键字,static、self、super 用实例说明

答 static: 静态全局变量,持久性作用、存储区域在静态区域,它的生命周期 和应用进行绑定。程序结束时,由系统自动回收。

self:当前消息的接收者。 super:向父类发送消息。

 

 

23、解释 self = [super init]方法

答:容错处理,当父类初始化失败,会返回一个 nil,表示初始化失败。由于继承的关系,子类是需要拥有父类的实例和行为的,因此,我们必须先初始化父类,然后再初始化子类。

 

 

24、当我们释放对象时,为什么需要调用[super dealloc] 方法?

答:(1)因为,子类是继承自父类,那么子类中有一些实例变量(对象),是 继承子父类的,因此,我们需要调用父类方法,将父类所拥有的实例进行释放。

(2)先将子类所拥有的实例进行释放,然后再释放父类的。 24、objective-c 有私方法么?私有变量呢?

答:是有的,我们称之为延展。私有变量也是有的(@private)。 25、以下每行代码执行后,person 对象的 retain count 分

别是多少?

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

                   

[person retain];// 2

[personrelease];  // 1

 

25、在某个方法中 self.name = _name 、name = _name 他们有区别吗,为什么?

答:是有区别的,前者是存在内存管理的,它会对_name 对象进行保留或者拷贝操作,而后者是普通赋值。

 

 

26、假设我们写了一个类的合成存取器,@property (nonatomic, copy) NSString*name;@synthesize name;

(1)NSString *aName= [NSString stringWithFormat:@”a”];

person.name =aName 此时 name 的引用计数是几,为什么,这么做

有什么好处?

答:它的引用技术是 2,相当于 retain 操作。

(2)NSMutableString*aName= [NSMutableString stringWithFormat:@”a”]; 同上

答:它的引用技术是 1,真正意义上的拷贝。

(3)返回这一个字符串的类型,是可变的吗?如果不是,为什么,我们又如何做?

答:不可变,因为合成存取器中用的 copy。如果,我们需要返回一个可变 的字符串时,那么必须自己实现 setter 和 getter 方法。

 

 

27、自动释放池是什么,如何工作

答:自动释放池是 NSAutorelease 类的一个实例,当向一个对象发送 autorelease 消息时,该对象会自动入池,待池销毁时,将会向池中所有对象发 送一条 release 消息,释放对象。[pool release]; [pool drain]表示的是池本身

                  

不会销毁,而是池子中的临时对象都被发送 release,从而将对象销毁。 28、为什么 delegate(代理)属性都是 assign 而不是 retain

的? 答:防止循环引用,以至对象无法得到正确的释放。

 

 

29、iOS开发中数据持久性,有哪几种。

 答:文件写入、对象归档、sqlite3 数据库、coredata

 

30、对象归档的基本概念,以及它的特点是什么?

答:归档为对象的数据持久化提供了一种解决方法,它特点是给归档的对象进行加密,增强了数据的安全性。此外,自定义类的对象归档必须实现 NSCoding 协议。

 

 

 

 

31、什么是 KVC 和 KVO?以及它们之间的关系是什么

答:(1)KVC(键值编码)是一种间接访问对象实例变量的机制,该机制可以 不通过存取方法就可以访问对象的实例变量。非对象类型的变量将被自动封装或 者解封成对象。此外,使用 KVC 能够简化代码。我们需要注意 KVC 有两个较为 明显的缺点,一旦使用 KVC 你的编译器无法检查出错误,即不会对设置的键、 键路径进行错误检查,且执行效率要低于(虽然效率已经很高,你已经感觉不到) 合成存取器方法和自定的 setter 和 getter 方法。因为使用 KVC 键值编码,它必 须先解析字符串,然后在设置或者访问对象的实例变量。

(2)KVO(键值观察)是一种能使得对象获取到其他对象属性变化的通知机制。

(3)实现KVO 键值观察模式,被观察的对象必须使用 KVC 键值编码来修改它的实例变量,这样才能被观察者观察到。因此,KVC 是 KVO 的基础或者说 KVO 的实现是建立在 KVC 的基础之上的。

 

 

32、在objective c 中如何实现 KVO

答:(1)注册观察者(这里我们需要注意,观察者和被观察者不会被保留也不 会被释放)

-(void)addObserver:(NSObject *)observer forKeyPath:(NSString *)keyPath

options:(NSKeyValueObservingOptions)options

context:(void*)context;

(2)接收变更通知

-(void)observeValueForKeyPath:(NSString *)keyPath

ofObject:(id)objectchange:(NSDictionary *)change context:(void *)context;

(3)移除对象的观察者身份

-(void)removeObserver:(NSObject *)observer

forKeyPath:(NSString*)keyPath;

 

 

 

33、当我们释放我们的对象时,为什么需要调用[super dealloc]方法,它的位置又是如何的呢?

答:因为子类的某些实例是继承自父类的,因此需要调用[super dealloc]方法,来释放父类拥有的实例,其实也就是子类本身的。一般来说我们优先释放子类拥有的实例,最后释放父类所拥有的实例。

 

 

                     

34、以下代码会出项问题吗?如果有,我们又该如何修 改?

@property(nonatomic, copy) NSMutableString *name; @synthesize name = _name;

self.name =[NSMutableString stringWithFormat:@"..xyz"]; [self.name insertString:@"abc"atIndex:0];

答:不可变字符串不可以被修改,可以通过自定义 set 方法,将字符串的拷贝改为可变的拷贝。

 

 

 

35、当我们将一个对象加入自动释放池时,该对象何时被销毁

答:我们在 application kit 应用程序中,自动释放池中的临时对象被销毁的时 间时,一个事件循环结束后。注意自动释放池没有被释放,而是被排空了,向池发送了 drain 消息。

 

 

36、当我们调用一个静态方法时,需要对对象进行 release 吗?

答:不需要,静态方法(类方法)创建一个对象时,对象已被放入自动释放池。在池被释放时,很有可能被销毁。

 

 

37、循环引用是什么,如何解决这样的问题?

答:对象 a 创建并引用到了对象 b;对象 b 创建并引用到了对象 c;对象 c 创建并引用到了对象 b。这时候 b 和 c 的引用计数分别是 2 和 1。

当 a 不再使用 b,调用 release 释放对 b 的所有权,因为 c 还引用了 b,所以 b 的引用计数为 1,b 不会被释放。

b 不释放,c 的引用计数就是 1,c 也不会被释放。从此,b 和 c 永远留在内存中。

这种情况,必须打断循环引用,通过其他规则来维护引用关系。我们常见的 delegate 往往是 assign 方式的属性而不是 retain 方式 的属性, 赋值不会增加引用计数,就是为了防止 delegation 两端产生不必要的循环引用。

 

 

38、isMemberOfClass和isKindOfClass 联系与区别

答:两者都能检测一个对象是否是某个类的成员, 两者之间的区别是:

isKindOfClass 不但可以用来确定一个对象是否是一个类的成员,也可以用来确 定一个对象是否是派生自该类的类的成员 ,而 isMemberOfClass 做不到后一点。

如 ClassA 派 生 自 NSObject 类 , ClassA *a = [ClassA alloc] init]; [aisKindOfClass:[NSObject class]] 可以检查出 a 是否是 NSObject 派生类 的成员,但 isMemberOfClass 做不到。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值