这里包含了去哪儿,滴滴,蚂蚁金服,美团,今日头条,快手以及其它公司的一些面试题,大部分面试官问的重复的问题不少,整体来讲就是如下的面试题。面试
- 简述iOS中的内存管理方式
iOS的内存管理用的是引用计数的方法,分为MRC(手动引用计数)和ARC(自动引用计数)。算法
MRC:开发者手动地进行retain和release操做,对每一个对象的retainCount进行+1,-1操做,当retainCount为0时,系统会自动释放对象内存。数据库
ARC:开发者经过声明对象的属性为strong,weak,retain,assign来管理对象的引用计数,被strong和retain修饰的属性变量系统会自动对所修饰变量的引用计数进行自增自减操做,一样地,retainCount为0时,系统会释放对象内存。api
- block的分类,__block的做用,block循环引用产生的缘由及解决办法
3.深拷贝与浅拷贝数组
深拷贝就是开辟一块新的内存空间来存储原来内存空间的内容,对象指针指向新的内存空间。浅拷贝只是从新生成一个指针,指向的仍是原来的内存空间。xcode
copy方法:若是是非可扩展类对象,则是浅拷贝。若是是可扩展类对象,则是深拷贝。浏览器
mutableCopy方法:不管是可扩展类对象仍是不可扩展类对象,都是深拷贝。缓存
注意:深拷贝和深复制不一样,深拷贝的内存空间的元素仍是指向原地址,可是深复制会开辟新的内存空间从新复制子元素。安全
4.iOS中常见的属性和默认的对象属性服务器
常见属性: atomic, nonatomic, assign, retain, strong, weak, copy, readonly, readwrite, unsafe_unretained, getter=, setter= 等。
默认属性: 继承于NSObject类的对象:(atomic, strong), 非继承于NSObject类的对象:(atomic, assign)
属性意义:
5.哪些属性须要声明成copy,为何?
@interface ViewController ()
@property (nonatomic, copy)NSString *aStr;
@property (nonatomic, strong)NSString *bStr;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
// [self buildUI];
[self testCode];
}
- (void)testCode{
NSMutableString *mutableStr = [NSMutableString stringWithFormat:@"%@", @"abc"];
self.aStr = mutableStr;
self.bStr = mutableStr;
[mutableStr appendString:@"123"];
NSLog(@"copy修饰的字符串:%@", self.aStr);
NSLog(@"strong修饰的字符串:%@", self.bStr);
}
复制代码
打印结果:
2018-05-22 21:13:58.344883 TTFeedBackDemo[1224:245923] copy修饰的字符串:abc
2018-05-22 21:13:58.345004 TTFeedBackDemo[1224:245923] strong修饰的字符串:abc123
复制代码
用了copy属性修饰以后,能够防止这些类型的对象被引用而且改变内容。
- 通知,代理,block,KVO的使用场景分别是什么,有什么区别?
通知: 适用于毫无关联的页面之间或者系统消息的传递,属于一对多的信息传递关系。例如系统音量的改变,系统状态的改变,应用模式的设置和改变,都比较适合用通知去传递信息。
代理: 一对一的信息传递方式,适用于相互关联的页面之间的信息传递,例如push和present出来的页面和原页面之间的信息传递。
block: 一对一的信息传递方式,效率会比代理要高(毕竟是直接取IMP指针的操做方式)。适用的场景和代理差很少,都是相互关联页面之间的页面传值。
KVO: 属性监听,监听对象的某一属性值的变化情况,当须要监听对象属性改变的时候使用。例如在UIScrollView中,监听contentOffset,既能够用KVO,也能够用代理。可是其余一些状况,好比说UIWebView的加载进度,AVPlayer的播放进度,就只能用KVO来监听了,不然获取不到对应的属性值。
- 简述对OC中的isa指针的认识
isa指针:首先,贴出NSObject.h文件,你们宏观感觉一下。
Ojective-C语言是基于C语言的封装,它实现了将面向过程的语言向面向对象的语言的转变。而OC中绝大部分类又是继承于NSObject类的,因此研究清楚NSObject类的构成,对于理解OC语言颇有帮助。#include <objc/objc.h>
、#include <objc/NSObjCRuntime.h>
,第一个头文件引入的是objc结构体的构成方式即isa指针,第二个头文件引入的是Runtime消息查找机制。@class NSString, NSMethodSignature, NSInvocation;
+ (NSString *)description
方法有关。isa指针: 代码以下
@interface NSObject <NSObject> {
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wobjc-interface-ivars"
Class isa OBJC_ISA_AVAILABILITY;
#pragma clang diagnostic pop
}
复制代码
NSObject对象其实包含了一个Class类型的isa指针。 这个和id类型是同样的,代码以下:
struct objc_object {
Class _Nonnull isa OBJC_ISA_AVAILABILITY;
};
/// A pointer to an instance of a class.
typedef struct objc_object *id;
复制代码
即id类型实际上是objc_object指针类型的别称。objc_object结构体一样也是包含了一个指向Class类型的指针。 继续看一下,Class isa指针的内部结构,以下
struct objc_class {
Class _Nonnull isa OBJC_ISA_AVAILABILITY;//指向元类的Class指针
#if !__OBJC2__
Class _Nullable super_class OBJC2_UNAVAILABLE;//指向父类的Class指针
const char * _Nonnull name OBJC2_UNAVAILABLE;//类名
long version OBJC2_UNAVAILABLE;//类的版本信息,默认为0
long info OBJC2_UNAVAILABLE;//运行期使用的一些位标识
long instance_size OBJC2_UNAVAILABLE;//该类的实例变量大小
struct objc_ivar_list * _Nullable ivars OBJC2_UNAVAILABLE;//属性列表
struct objc_method_list * _Nullable * _Nullable methodLists OBJC2_UNAVAILABLE;//方法列表
struct objc_cache * _Nonnull cache OBJC2_UNAVAILABLE;//缓存方法列表
struct objc_protocol_list * _Nullable protocols OBJC2_UNAVAILABLE;//协议列表
#endif
} OBJC2_UNAVAILABLE;
typedef struct objc_class *Class;
复制代码
Class其实就是一个objc_class类型的结构体指针。objc_class的结构体变量构成见上图,下面是objc_class类的super_class指针和isa元类指针的具体指向关系,请你们分清对象,对象的类,元类,根元类这些概念。
- 简述OC中的消息转发机制
当objc_msgSend方法调用找不到响应的函数名称时就会进行消息转发,主要分为3步:
调用方法+(BOOL)resolveInstanceMethod:(SEL)sel
(实例方法动态解析)和+ (BOOL)resolveClassMethod:(SEL)sel
(类方法动态解析)。
调用方法 - (id)forwardingTargetForSelector:(SEL)aSelector
调用方法- (void)forwardInvocation:(NSInvocation *)anInvocation
和- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector
具体的转发流程见下图:
- 响应链原理
当用户触摸屏幕时,触碰屏幕产生事件UIEvent并存入UIApplication中的事件队列中, 而且在整个视图结构中自上而下的进行分发,以下图所示:
这里着重介绍两个方法
//判断当前点击事件是否存在最优响应者(First Responder)
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event;
复制代码
//判断当前点击是否在控件的Bounds以内
- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event;
复制代码
第一个方法返回一个能够响应event触摸事件的UIView,第二个方法判断触摸点位在不在可相应范围以内的BOOL值。因此会衍生出一些问题,好比说“如何让一个父视图之外的子视图响应点击事件”,“如何只让一个UIView的圆形区域响应触摸事件”等等,在此因为篇幅限制,再也不一一展开详述。下面这幅图简述了系统查找响应事件控件的流程。
- 手写一个block结构体声明
typedef void(^RBBlogDemoHandler)(void);
- RunLoop原理,RunLoop与线程的关系
- GCD与NSOperation两种管理多线程方式的异同点
- GCD的经常使用api
- GCD中的同步异步,串行并发的概念,GCD常见的线程死锁问题
dispatch_sync(dispatch_get_main_queue(), ^{
NSLog(@"%@", @"123");
});
复制代码
这样的函数,就是典型的GCD死锁函数。 由于dispatch_sync阻塞的当前的线程,而当前线程是main_queue,也就是说是一个串行线程,当前线程只有先执行NSLog(@"%@", @"123")
才能继续运行下去,可是当前线程又被阻塞掉了,没法向下继续执行,因此这就是一个死锁的GCD执行函数了。
- iOS中经常使用的线程锁有哪些,分别具备哪些特色?
dispatch_barrier_async
/dispatch_barrier_sync
,dispatch_barrier_async
/dispatch_barrier_sync
在必定的基础上也能够作线程同步,会在线程队列中打断其余线程执行当前任务。两个的区别是dispatch_barrier_async阻塞的是当前队列的线程,而dispatch_barrier_sync阻塞的是任务所插入队列的线程。
- Father的子类Son,分别写出
NSStringFromClass([self class])
,NSStringFromClass([super class])
,NSStringFromClass(self.superClass)
的打印值
- KVO的原理
willChangeValueForKey:
(值改变以前)和didChangevlueForKey:
(值改变以后)。在一个被观察属性发生改变以前,willChangeValueForKey:
必定会被调用,这就会记录旧的值。而当改变发生后,didChangeValueForKey:
会被调用,继而observeValueForKey:ofObject:change:context:
也会被调用。
- runtime的机制和应用
19.MJExtension, MJRefresh, SDWebImage的实现原理
- NSTimer计时器是准确的吗,为何?
- 类的分类和类的扩展的区别,类的分类的实现原理。
- iOS动态关联属性(
objc_setAssociatedObject
,objc_getAssocicatedObject
)的实现原理
- Masonry的抗压缩属性和抗拉伸属性
[label1 setContentHuggingPriority:UILayoutPriorityRequired
forAxis:UILayoutConstraintAxisHorizontal];
[label2 setContentHuggingPriority:UILayoutPriorityDefaultLow
forAxis:UILayoutConstraintAxisHorizontal];
复制代码
[label1 setContentCompressionResistancePriority:UILayoutPriorityDefaultLow
forAxis:UILayoutConstraintAxisHorizontal];
[label2 setContentCompressionResistancePriority:UILayoutPriorityRequired
forAxis:UILayoutConstraintAxisHorizontal];
复制代码
- 加密的种类,对称加密和非对称加密
- 解释一下七层网络结构,三次握手协议和四次挥手协议
七层网络协议:
三次握手协议:
四次挥手协议:
- http和https的区别
- https双向验证原理
- HTTP经常使用的头部字段,常见的返回状态码和意义
常见的头部字段:
返回的状态码:
- @class和import以及include的区别
- weak对象的管理方式
weak是弱引用,所引用对象的计数器不会加一,并在引用对象被释放的时候自动被设置为nil。runtime维护了一个weak表,用于存储指向某个对象的全部weak指针。weak表实际上是一个hash(哈希)表,Key是所指对象的地址,Value是weak指针的地址(这个地址的值是所指对象的地址)数组。
一、初始化时:runtime会调用objc_initWeak函数,初始化一个新的weak指针指向对象的地址。
二、添加引用时:objc_initWeak函数会调用 objc_storeWeak() 函数, objc_storeWeak() 的做用是更新指针指向,建立对应的弱引用表。
三、释放时,调用clearDeallocating函数。clearDeallocating函数首先根据对象地址获取全部weak指针地址的数组,而后遍历这个数组把其中的数据设为nil,最后把这个entry从weak表中删除,最后清理对象的记录。
- iOS的retain和release的操做是在编译期仍是运行时进行的
- (void) setUserName:(UITextField *)userName {
[_userName release];
_userName = [userName retain];
}
复制代码
- +(void)load方法和+(void)initial方法的异同
当一个视图控制器被建立,并在屏幕上现实的时候。代码的执行顺序:
当一个视图被移除屏幕而且销毁的时候执行顺序:
- iOS中各种控件的继承树关系
- 如何化解NSTimer的循环引用关系
- 怎样管理第三方SDK,CocoaPods和Carthage的异同
iOS中通常使用CocoaPods和Carthage来管理第三方SDK。
二者的比较:
- -(BOOL)isKindOfClass和-(BOOL)isMemberOfClass的区别
-(BOOL) isKindOfClass: classObj 判断是不是这个类或者这个类的子类的实例
-(BOOL) isMemberOfClass: classObj 判断是不是这个类的实例
- 数据持久化的几种方式和对应的应用场景
- 如何实现一个完整的单例
#import "Singleton.h"
@interface Singleton()<NSCopying,NSMutableCopying>
@end
@implementation Singleton
static Singleton* _instance = nil;
+(instancetype) shareInstance
{
static dispatch_once_t onceToken ;
dispatch_once(&onceToken, ^{
_instance = [[super allocWithZone:NULL] init] ;
//不是使用alloc方法,而是调用[[super allocWithZone:NULL] init]
//已经重载allocWithZone基本的对象分配方法,因此要借用父类(NSObject)的功能来帮助出处理底层内存分配的杂物
}) ;
return _instance ;
}
+(id) allocWithZone:(struct _NSZone *)zone
{
return [Singleton shareInstance] ;
}
-(id) copyWithZone:(NSZone *)zone
{
return [Singleton shareInstance] ;//return _instance;
}
-(id) mutablecopyWithZone:(NSZone *)zone
{
return [Singleton shareInstance] ;
}
@end
复制代码
- iOS的系统单例有哪些?
[UIScreen mainScreen] (应用程序窗口)
[UIDevice currentDevice] (当前设备)
[UIApplication sharedApplication] (应用程序实例)
[NSNotificationCenter defaultCenter] (消息中心):
[NSFileManager defaultManager] (文件管理):
[NSUserDefaults standardUserDefaults] (应用程序设置):
[NSURLCache sharedURLCache] (请求缓存):
[NSHTTPCookieStorage sharedHTTPCookieStorage] (应用程序cookies池)
- APP启动主要流程
- iOS的沙盒机制
出于安全考虑,iPhone对于安装在上面的应用程序有所限制,这个限制就是应用程序只能在为该改程序建立的文件系统中读取文件,不能够去其它地方访问,此区域被成为沙盒,因此全部的非代码文件都要保存在此,例如图像,图标,声音,映像,属性列表,文本文件等。整体来讲沙盒就是一种独立、安全、封闭的空间。沙盒(sandbox)的核心内容是:sandbox对应用程序执行各类操做的权限限制。
沙盒的特色:
应用程序沙盒目录下有三个文件夹Documents、Library(下面有Caches和Preferences目录)、tmp。