iOS程序员面试题系列(4)

本文详细介绍了Objective-C编程的基础知识,包括属性关键字、ARC模式、GCD队列、深复制与浅复制、类别作用、多继承替代方案、数组与指针区别、static作用、内存分区情况、MVC理解、frame与bounds区别、HTTP协议中POST与GET的区别、iOS系统架构、XIB文件构成、视图控制器生命周期、简单表格视图显示设置、UIView与CALayer区别等内容。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.什么时候使用weak关键字,相比assign有什么不同?

答:(1)什么情况使用weak关键字?

a.在ARC中,在有可能出现循环引用的时候,往往要通过让其中一端使用weak来解决,比如:delegate代理属性。

b.自身已经对它进行一次强引用,没有必要再强引用一次,此时也会使用weak,自定义IBOutlet控件属性一般也使用weak;当然,也可以使用strong。

(2)不同点:

a.weak此特质表明该属性定义了一种“非拥有关系”(nonowning relationship)。为这种属性设置新值时,设置方法既不保留新值,也不释放旧值。此特质同assign类似,然而在属性所指的对象遭到摧毁时,属性值也会清空(nil out)。而assign的“设置方法”只会执行针对“纯量类型”(scalar type,例如CGGFloat或NSInteger等)的简单赋值操作。

b.assign可以用非OC对象,而weak必须用于OC对象。


2.怎么使用copy关键字?

a.NSString、NSArray、NSDictionary等等经常使用copy关键字,是因为他们有对应的可变类型:NSMutableString、NSMutableArray、NSMutableDictionary;

b.block也经常使用copy关键字,block使用copy是从MRC遗留下来的“传统”,在MRC中,方法内部的block是在栈区的,使用copy可以把它放到堆区。在ARC中写不写都行:对于block使用copy还是strong效果是一样的,但写上copy也无伤大雅,还能时刻提醒我们:编译器自动对block进行了copy操作。

用@property声明NSString、NSArray、NSDictionary经常使用copy关键字,是因为它们有对应的可变类型:NSMutableString、NSMutableArray、NSMutableDictionary,他们之间可能进行赋值操作,为确保对象中的字符串值不会无意间变动,应该在设置新属性值时拷贝一份。


3.@propery中有哪些属性关键字?/@property后面可以有哪些修饰符?

答:属性可以拥有的特质分为四类:

1) 原子性---nonatomic特质

在默认情况下,有编译器合成的方法会通过锁定机制确保其原子性(atomicity)。如果属性具备nonatomic特质,则不使用同步锁。请注意,尽管没有名为“atomic”的特质(如果某属性不具备nonatomic特质,那它就是“原子的”(atomic)),但是仍然可以在属性特质中写明这一点,编译器不会报错。若是自己定义存取方法,那么就应该遵从与属性特质相符的原子性。

2) 读/写权限---readWrite(读写)、readonly(只读)

3) 内存管理语义---assign、strong、weak、unsafe_unretained、copy

4) 方法名---getter=、setter=。


4.@synthesize和@dynamic分别有什么作用?

答:1)@property有两个对应的词,一个是@synthesize,一个是@dynamic。如果@synthesize和@dynamic都没写,那么默认的就是@synthesize var = _var。

2)@synthesize的语义是如果你没有手动实现setter方法和getter方法,那么编译器会自动为你加上这两个方法。

3)@dynamic告诉编译器:属性的setter与getter方法由用户自己实现,不自动生成。(当然对于readonly的属性只需提供getter即可)。假如一个属性被声明为@dynamic var,然后你没有提供@setter方法和@getter方法,编译的时候没问题,但是当程序运行到instance.var=someVar,由于缺setter方法会导致程序崩溃;或者当运行到someVar = var时,由于缺getter方法同样会导致崩溃。编译时没问题,运行时才执行相应的方法,这就是所谓的动态绑定。


5.ARC模式下,不显示指定任何属性关键字时,默认的关键字都是哪些?

1)对应基本数据类型默认关键字是:atomic,readwrite,assign

2)对于普通的OC对象默认关键字是:atomic,readwrite,strong。


6.用@property声明的NSString(或NSArray,NSDictionary)经常使用copy关键字,为什么?如果改用strong关键字,可能造成什么问题?

答:1)因为父类指针可以指向子类对象,使用copy的目的是为了让本对象的属性不受外界影响,使用copy无论给我传入是一个可变对象还是不可变对象,我本身持有的就是一个不可变的副本。

2)如果我们使用strong,那么这个属性就有可能指向一个可变对象,如果这个可变对象在外部被修改了,那么会影响该属性。


7.GCD的队列(dispatch_queue_t)分哪两种类型?

1.串行队列Serial Dispatch Queue

2.并行队列Concurrent Dispatch Queue。


8.深复制和浅复制的区别是什么?

答:简单的来说就是,在有指针的情况下,浅拷贝知识增加了一个指针指向已经存在的内存,而深拷贝就是增加一个指针并且申请一个新的内存,使这个增加的指针指向这个新的内存,采用深拷贝的情况下,释放内存的时候就不会出现在浅拷贝时重复释放同一内存的错误。

1)浅复制(copy):只复制指向对象的指针,而不复制引用对象本身。

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


9.类别的作用?

答:有时我们需要在一个已经定义好的类中增加一些方法,而不想去重写该类。比如当工程已经很大,代码量比较多,或者类中已经包括了很多方法,已经有其他代码调用了该类创建对象并使用该类的方法时,可以使用类别对该类扩充新的方法。

注意:类别只能扩充方法,而不能扩充成员变量。


10.Objective-C有多继承吗?没有的话用什么代替?

答:cocoa中所有的类都是NSObject的子类

多继承在这里是用Protocol委托代理来实现的。

你不用去考虑繁琐的多继承,虚基类的概念。

Ood的多态特性,在Objective-C中通过委托来实现。


11.数组和指针的区别:

答:1)数组可以申请在栈区和数据区,指针可以指向任意类型的内存块;

2)sizeof作用于数组时,得到的是数组所占的内存大小;作用于指针时,得到的都是4个字节的大小。

3)数组名表示数组首地址,值不可以改变,如不可以将++作用于数组名上;普通指针的值可以改变,如可将++作用于指针上;

4)用字符串初始化字符数组是将字符串的内容拷贝到字符数组中;用字符串初始化字符指针是将字符串的首地址赋给指针,也就是指针指向了该数组。


12.static的作用

答:1)函数体内static变量的作用范围为该函数体,不同于auto变量,该变量的内存只被分配一次,因此其值在下次调用时扔维持上次的值;

2)在模块内的static全局变量可以被模块内的所有函数调用,但不能被模块外其他函数访问;

3)在模块内的static函数只可被这一模块内的其他函数调用,这个函数的使用范围被限制在声明它的模块内;

4)在类中的static成员变量属于整个类所拥有,对类的所有对象只有一份拷贝;

5)在类中的static成员函数属于整个类所拥有,这个函数不接收this指针,因而只能访问类的static成员变量。


13.简述内存分区情况

答:1)代码区:存放函数二进制代码;

2)数据区:系统运行时申请内存并初始化,系统退出时由系统释放。存放全局变量、静态变量、常量;

3)堆区:通过malloc等函数或new等操作符动态申请得到,需程序员手动申请和释放;

4)栈区:函数模块内申请,函数结束时由系统自动释放。存放局部变量、函数参数。


14.MVC的理解

答:MVC模式考虑三种对象:模型对象、视图对象和控制器对象。模型对象负责应用程序的数据和定义操作数据的逻辑;视图对象知道如何显示应用程序的模型数据;控制器对象是M与V之间的协调者。


15.frame和bounds有什么不同?

答:frame指的是,该view在父view坐标系统中的位置和大小。(参照点是父亲的坐标系统)

Bounds指的是,该view在本身坐标系统中的位置和大小。(参考点是本身坐标系统)


16.HTTP协议中,POST和GET的区别是什么?

答:1)GET方法

GET方法提交数据不安全,数据置于请求行,客户端地址栏可见;

GET方法提交的数据大小有限;

GET方法不可以设置书签。

2)POST方法

POST方法提交数据安全,数据置于消息主体内,客户端看不见;

POST方法提交的数据大小没有限制;

POST方法可以设置书签。


17.iOS的系统架构分为:

1)核心操作系统层:the Core OS layer;

2)核心服务层:the Core Service layer;

3)媒体层:the Media layer;

4)Cocoa界面服务层the CocoaTouch layer。


18.xib文件的构成分为哪三个图标?都具有什么功能?

答:File’s Owner是所有nib文件中的每个图标,它表示从磁盘加载nib文件的对象;

First Responder就是用户当前正在与之交互的对象;

View显示用户界面;完成用户交互;是UIView类或其子类。


19.简述视图控制器的生命周期

答:loadView尽管不直接调用该方法,如多手动创建自己的视图,那么应该覆盖这个方法并将它们赋值给视图控制器的view属性。

viewDidLoad只有在视图控制器将其视图载入到内存之后才调用该方法,这是执行任何其他初始化操作的入口。

viewDidUnload当视图控制器从内存释放自己的方法的时候用,用于清除那些可能已经在视图控制器中创建的对象。

viewWillAppear当视图将要添加到窗口中并且还不可见的时候或者上层视图移出图层后本视图变成顶级视图时调用该方法,用于执行诸如改变视图方向等的操作。实现该方法时,确保调用[super viewWillAppear]。

viewDidAppear当视图添加到窗口中以后或者上层视图移出图层后本视图变成顶级视图时调用,用于放置那些需要在视图显示后执行的代码。确保调用[super viewDidAppear]。


20.实现简单的表格显示需要设置UITableView的什么属性、实现什么协议?

答:实现简单的表格显示需要设置UITableView的dataSource和delegate属性,实现UITableViewDataSource和UITableViewDelegate协议。


21.UIView与CALayer有什么区别?

答:1)UIView是iOS系统中界面元素的基础,所有的界面元素都是继承自它。它本身完全是由CoreAnimation来实现的。它真正的绘图部分,是由一个CALayer类来管理的。UIView本身更像是一个CALayer的管理器,访问它的跟绘图和跟坐标有关的属性。

2)UIView有个重要属性layer,可以返回它的主CALayer实例。

3)UIView的CALayer类似UIView的子View树形结构,它可以向它的layer上添加子layer,来完成某些特殊的表示,即CALayer层是可以嵌套的。

4)UIView的layer树形在系统内部,被维护着三份copy。分别是逻辑树,这里是代码可以操纵的;动画树,是一个中间层,系统就在这一层上更改属性,进行各种渲染操作;显示树,其内容就是当前正被显示在屏幕上的内容。

5)动画的运作:对UIView的subLayer(非主layer)属性进行更改,系统将自动进行动画生成,动画持续时间的缺省值似乎是0.5秒。

6)坐标系统:CALayer的坐标系统比UIView多了一个anchorPoint属性,使用CGPoint结构表示,值域是0~1,是一个比例值。这个点是各种图形变换的坐标原点,同时会更改layer的position的位置,它的缺省值是{0.5,0.5},即在layer的中央。

7.渲染:当更新层,改变不能立即显示在屏幕上。当所有的层都准备好时,可以调用setNeedsDisplay方法来重绘显示。

8)变换:要在一个层中添加一个3D或仿射变换,可以分别设置层的transform或offline Transform属性。

9)变形:Quartz Core的渲染能力,使二维图像可以被自由操纵,就好像是三维的。图像可以在一个三维坐标系中以任意角度被旋转,缩放和倾斜。CATransform3D的一套方法提供了一些魔术般的变换效果。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值