面试题转载

iOS面试题

基础篇

Objective-C的类可以多重继承么?可以采用多个协议么?

不可以多重继承,可以采用多个协议.

objc使用什么机制管理对象内存?

1、手动引用计数
2、自动引用计数,现在通常使用自动引用计数

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

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

描述一下iOS SDK中如何实现MVC的开发模式

MVC是模型、视图和控制开发模式,对于iOS SDK所有view都是视图层的,它应该都独立于模型层,由控制层来控制。所有的用户数据都是模型层,它应该独立于视图层。所有的ViewController都是控制层,它负责控制视图,访问模型数据。

浅复制和深复制的区别?

浅复制:只是复制了指向对象的指针,而不复制对象本身。
深复制:复制引用对象本身。

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

category是什么? 扩展一个类的方式用继承好还是类目好? 为什么?

category是类目,当然类目好,因为继承要满足A is a B的关系,而类目只需要满足A has a B的关系,局限性更小,你不用定义子类就能扩展一个类的功能,还能将类的定义分开放在不同的源文件里,用category去重写类的方法,仅对本category有效,不会影响到其他类与原有类的关系。

延展是什么? 作用是什么?

延展(extension):在自己类的实现文件中添加类目来声明私有方法。

解释一下懒汉模式?

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

#进阶篇

@property中有哪些属性关键字?

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

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

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

3、内存管理语义 – assign、strong、 weak、copy

4、方法名 —- getter= 、setter=

你经常使用一些第三方库有哪些?

1.AFNetworking

2.SDWebImage

3.FMDB (没怎么用,得学习)

4.JSONKit

5.MJRefresh

6.MJExtension(需要再复习)

7.Masonry

8.友盟,shareSDK等三方库。

你经常用的设计模式有哪些?

1.MVC

2.代理模式 (Delegate)

3.观察者模式 (NSNotification/KVO)

4.单例模式 (需要多使用)

5.工厂模式 – 简单工厂,工厂方法, 抽象工厂三种设计模式(需要多使用)

本地存储有哪些方式?

1.属性列表(NSUserDefault 或 plist)

2.对象归档 (NSKeyedArchiver)

3.SQLite

4.CoreData

weak属性需要在dealloc中置nil么?

不需要,在ARC环境无论是强指针还是弱指针都无需在deallco设置为nil,ARC会自动帮我们处理。

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

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

2、@synthesize:如果你没有手动实现setter方法和getter方法,编译器自动生成setter和getter方法

3、@dynamic:不会生成setter和getter方法,用户自己实现

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

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

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

什么时候会报unrecognized selector的异常?

当该对象上某个方法,而该对象上没有实现这个方法的时候

使用block时什么情况会发生引用循环,如何解决?

1、只要是一个对象对该block进行了强引用,,在block内部有直接使用到该对象。

2、解决方案:__weak id weakSelf = self;

使用系统的某些block api(如UIView的block版本写动画时),是否也考虑引用循环问题?

不需要考虑,因为官方文档中没有告诉我们要注意发生强引用,所以推测系统控件一般没有对这些block进行强引用,所以我们可以不用考虑循环强引用的问题

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

串行队列和并行队列

如何用GCD同步若干个异步调用?(如根据若干个url异步加载多张图片,然后在都下载完成后合成一张整图)

总体上说: 使用 dispatch group,然后 wait forever 等待完成, 或者采取 group notify 来通知回调。

1
2
3
4
5
6
7
8
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_group_t group = dispatch_group_create();
dispatch_group_async(group, queue, ^{ /*加载图片1 */ });
dispatch_group_async(group, queue, ^{ /*加载图片2 */ });
dispatch_group_async(group, queue, ^{ /*加载图片3 */ });
dispatch_group_notify(group, dispatch_get_main_queue(), ^{
// 合并图片
})

以下代码运行结果如何?

1
2
3
4
5
6
7
8
9
- (void)viewDidLoad
{
[super viewDidLoad];
NSLog(@"1");
dispatch_sync(dispatch_get_main_queue(), ^{
NSLog(@"2");
});
NSLog(@"3");
}

只输出1,然后主线程锁死

若一个类有实例变量NSString *_foo,调用setValue:forKey:时,可以以foo还是_foo作为key?

都可以–可以根据kvc的底部实现来解释

IBOutlet连出来的视图属性为什么可以被设置成weak?

因为视图已经对它有一个强引用了

你单例怎么理解怎么用的? —- ※

Singleton Pattern单例设计模式,通过单例模式可以保证系统中只有一个实例而且该实例易于外界访问,从而方便对实例个数的控制节约系统资源。如果希望在系统的某个类的对象只能存在一个,单例模式是最好的解决方案。类只能有一个实例,而且必须从一个为人熟知的访问点进行访问,比如工厂方法。这个唯一的实例只能通过子类化进行扩展,而且扩展对象不会破坏客户端代码。例如,UIApplication的sharedApplication方法,任何时候都会返回一个当前应用程序的UIApplication实例。

lldb(gdb)常用的调试命令?

最常用就是:po 对象

什么是谓词?

谓词是通过NSPredicate,是通过给定的逻辑条件,完成对数据的筛选

+(void)load; +(void)initialize; 的区别?

+(void)load:在程序执行后运行

+(void)initialize:在类的方法第一次被调时执行

什么是KVC,什么是KVO?

KCV:键 - 值编码是对象的一种间接访问属性使用字符串来标识属性,而不是通过调用存取方法,直接或通过实例变量访问的机制。

KVO: 键 - 值观察机制,提供了观察某一属性变化的方法,极大的简化了代码。

什么时候用delegate,什么时候用Notification?

delegate是一对一,并且接受者可以返回值给发送者(反向传值);Notification是一对一也可以一对多,接受者无法可以返回值给发送者。所以,delegate用于发送者希望受到接受者的某个功能的反馈值。notification用于通知多个object某个事件

block和weak区别?

1、__block不管是在ARC还是MRC的模式下都可以使用,可以修饰对象,也可以修饰数据类型

2、weak只能在ARC模式下使用,只能修饰对象不能修饰数据类型

3、block对象可以在block被重新赋值,但weak不行

frame和bounds有什么不同?

frame:该view在父视图坐标的位置和大小(参照点是父亲的坐标系统);bounds:该view本身坐标的位置和大小(参照点是本身坐标系统)

UIView和CALayer有什么不同?

两者最大的区别是图层不会直接渲染到屏幕上,UIView是iOS系统中界面的元素,所有的界面元素都是继承自它。它本身完全是由CoreAnimation来实现。它真正绘图部分,是由一个CALayer类来管理。UIView本身更像一个CAlayer的管理器。一个UIView上可以有N个CALayer,每个layer显示一种东西,增强UIView的展现能力。

TCP和UDP的区别?

TCP(传输控制协议):提供面向连接的、可靠地点对点的通信

UDP(用户数据报协议):提供非面向连接的、不可靠地点对多点的通信

socket连接与http连接

Socket:长链接,即客户端一旦与服务器建立起链接,便不会主动断掉

http:短链接,即客户端向服务端发起一次请求,链接立即断开

HTTP 的post与get区别与联系,实践中如何选择它们?

1、get是服务器上获取数据,post是向服务器发送数据

2、在客户端,get方式,在通过URL提交数据,数据可以在URL中可以看到;post方式,数据放置在HTML HEADER内提交

3、对于get方式,服务器用Request.QueryString获取变量的值;post方式,服务器用Request.From获取提交的数据

4、Get方式提交数据最多1024字节,post则没有限制

5、安全性问题。正如在(1)中提到,使用 Get 的时候,参数会显示在地址栏上,而 Post 不会。所以,如果这些数据是中文数据而且是非敏感数据,那么使用 get;如果用户输入的数据不是中文字符而且包含敏感数据,那么还是使用 post为好。
Http定义了与服务器交互的不同方法,最基本的方法有4种,分别是GET,POST,PUT,DELETE。URL全称是资源描述符,我们可以这样认为:一个URL地址,它用于描述一个网络上的资源,而HTTP中的GET,POST,PUT,DELETE就对应着对这个资源的查,改,增,删4个操作。GET一般用于获取/查询资源信息,而POST一般用于更新资源信息。

检查内存管理问题的方式有哪些

1、点击Xcode顶部菜单栏Product–Analyze。这种方法可以查看内存泄露,变量未初始化,变量定义后没有被使用到

2、使用Instrument工具检查。点击Xcode顶部菜单中的Product Profile,弹出一个界面,选择左侧的Memory后,再选右侧的Leaks。

3、人工检查

谈安卓与苹果的优缺点

苹果系统优点是左右流畅,软件多,界面华丽,图标统一,很美观;缺点是系统封闭,不允许用户过多的个性化设置,而且只能在苹果手机上用。安卓系统优点是开放,可以自己扩展的东西很多,支持的硬件也多,各个价位的手机都有;缺点就是软件太杂乱,兼容性有问题,图标混乱不美观。iOS的确比android流畅,这仅仅体现在较大软件切换时,其他差不多流畅,iOS并不能做到完全后台,如果它完全后台估计也不会比安卓流畅多少。反之,如果安卓只是注重单个运行,流畅度也会大大提升,iOS系统更新没有android那么频繁,爱体验的人会选安卓,那些怕烦的会选iOS。iOS的硬件需求选不及android,以至于android机会相对iOS较热,较费电额。

大神篇

运行时你是怎么理解的?

ObjC Runtime其实是一个Runtime库,基本使用C和汇编的,这个库是得C语言有了面向对象的能力。这个库的事情就是加载类的信息,进行方法的分发和转发之类的。OC是一种runtime(运行时)的语言,也就是说,它会尽可能的把代码执行的决策从编译和链接的时候,推迟到运行时。这给程序员写代码带来很大的灵活性,比如说你可以把你消息转发给你想要的对象,或者可以随意交换一个方法的实现之类的。这就要求runtime能检测到一个对象是否能对一个方法的响应,然后再把这个方法分发到对应的对象中去。

@protocol 和 category 中如何使用 @property

1、在@protocol只生成setter和getter方法声明,我们使用属性的目的,是希望遵守我协议的对象实现该属性

2、category 使用 @property 也是只会生成 setter 和 getter 方法的声明,如果我们真的需要给category增加属性的实现,需要借助运行时的两个函数① objc_setAssociatedObject ②objc_getAssociatedObject

runtime如何通过selector找到对应的IMP地址?

每一个对象都有一个方法列表,方法列表中记录着方法名称,方法实现以及参数类型,其实selector本质就是方法名称,通过这个方法名称就可以在方法列表中找到相应的方法实现

一个objc对象如何进行内存布局?

1、所有父类的成员变量和自己的成员变量都会存放在该对象所对应的存储空间中

2、每个对象内部都有一个isa指针,指向它的类对象,类对象中存放着本对象

对象方法列表(对象能够接收的消息列表,保存在它所对应的类对象)

成员变量的列表

属性列表

它内部也有一个isa指针指向元对象(meta class),元对象内部存放着类方法列表,类对象内部存放着一个superclass的指针,指向它的父对象

本篇文章转载自一个低调的iOS开发