《招聘一个靠谱的iOS》面试题参考答案

来源:互联网 发布:手机淘宝充值中心在哪 编辑:程序博客网 时间:2024/04/29 02:13

说明:面试题来源是微博@我就叫Sunny怎么了的这篇博文:《招聘一个靠谱的 iOS》下面是我对这个面试题的解答
本人iOS github:https://github.com/netyouli?tab=repositories 欢迎mark star。

1.[※]@property中有哪些属性关键字?

(nonatomic, atomic , strong , retain , copy , week , assign , setter , getter , readwrite ,readonly)

2.[※]strong 和retain有什么区别 week 和 assign有什么区别?

(strong 和 retina 基本一样在进行setter方法时会release 旧 retina新 strong 是ARC模式下默认属性关键字,week在对象被释放的时候会自动把对象设置为nil而不会成为野指针,assign不会设置成nil导致对象变成野指针)

3.[※]weak属性需要在dealloc中置nil么?

(不需要,看上题答案解析)

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

(@synthesize 在编译的时候会自动加入getter 和 setter方法以及默认私有成员对象在xcode5.0以后@synthesize可以不写,

实例:

@property (strong) NSString * whc;

@synthesize whc;

在编译的时候xcode会自动帮我们生成如下方法:

默认私有对象为:NSString * _whc;

-(void)setWhc:(NSString *)whc{       [_whc release];      _whc = [whc retain]; }-(NSString *)whc{      return _whc;}

@dynamic 在编译时不会自动生成getter 和 setter 方法,而是在运行时动态在 + (BOOL)resolveInstanceMethod:(SEL)aSEL

方法里指定getter 和 setter方法名称并且动态添加。

例如:

定义private 对象NSString * _whc;

@dynamic wHC;void setWHC(id self, SEL _cmd , NSString whc) {    // implementation ….       _whc = whc.copy;}NSString * wHC(id self , SEL _cmd){    return _whc;}+ (BOOL)resolveInstanceMethod:(SEL)aSEL{    if (aSEL == @selector(setWHC:)) {          class_addMethod([self class], aSEL, (IMP) setWHC, "v@:@");//v表示返回类型void 后面三个以此表示(@表示self,:表示_cmd,@表示whc)          return YES;    }else if(aSEL == @selector(wHC)){         class_addMethod([self class], aSEL, (IMP) wHC,"@@:");// 后面三个以此表示(@表示返回类型NSString,@表示self,:表示_cmd         return YES;    })    return [super resolveInstanceMethod:aSEL];}@end)

5.[※※※]ARC下,不显式指定任何属性关键字时,默认的关键字都有哪些?

(对象类对象属性默认关键字有:nonatomic , strong , readwrite , setter , getter 对于内建类型属性是默认关键字有:nonatomic , assgin , readwrite, setter , getter )

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

(首先copy属性关键字作用复制一个对象使这两个对象没有引用关联,strong 属性关键字不会复制一个对象赋值对象和被赋值对象有引用关联。

如果我们需求是:在对NSString(或NSArray,NSDictionary)类型属性赋值给其他对象,而以后操作被赋值对象要反应到属性对象上来的时候这个时候我们需要用 strong属性关键字。如果使用copy关键则以后操作被赋值的对象时不会反应到属性对象上从而引发值不对等的问题。)

7.[※※※]@synthesize合成实例变量的规则是什么?假如property名为whc,存在一个名为_whc的实例变量,那么还会自动合成新变量么?

(@synthesize默认情况下会生成whc私有实例变量,同时也可以自定义私有变量名称如@synthesize whc = _whc 此时如果存在一个自定义_whc实例变量那么会报错)

8.[※※※※※]在有了自动合成属性实例变量之后,@synthesize还有哪些使用场景?

(看上题解答分析)

9.[※※]objc中向一个nil对象发送消息将会发生什么?

(什么也不会发生,首先objc会检查要接收消息的对象是否有值如果为nil直接return 什么也不会发生,风平浪静 )

10.[※※※]objc中向一个对象发送消息[obj foo]和objc_msgSend()函数之间有什么关系?

([obj foo]; 调用运行时会转换为objc_msgSend(obj , @selector(foo));

)

11.[※※※]什么时候会报unrecognized selector的异常?

(在运行时往往会出现这个crash,主要原因是定义对象obj类型的时候和运行过程创建obj对象的时候类型不一致,如:

@property (nonatomic , strong)NSString * whc;

在程序运行的时候异常创建whc = [NSNull new];

后面运行使用whc依然当NSString使用如:int = len = whc.length;这个时候就会出现unrecognized selector的异常。)

12.[※※※※]一个objc对象如何进行内存布局?(考虑有父类的情况)

(先创建父类然后创建子类内存布局大概是这样:objc中创建一个对象内存中都将包含isa指针和父类指针(前提是有父类)和调度表,这个isa指针指向该类实例方法和实例变量调度表并且该调度表里也有一个isa指针该调度表里的isa指针对象该类相关调度表如类方法,类名称,类版本,子类对象里的父类指针是指向父类内存地址的)

13.[※※※※]一个objc对象的isa的指针指向什么?有什么作用?

(指向什么看上一题解答分析,我们来分析一下isa指针作用:

在我们程序运行调用某对象里的变量或者方法时isa指针就会在调度表里查询该对象是否有该实例变量或者方法如果有那么就调用,如果没有那么就向父类的调度表查询依次往上查询,最后如果还是没有这会unrecognized selector的异常

)

14.[※※※※]下面的代码输出什么?

@implementation Son : Father- (id)init{    self = [super init];    if (self) {        NSLog(@"%@", NSStringFromClass([self class]));        NSLog(@"%@", NSStringFromClass([super class]));    }    return self;}@end

(Son,Son (父类没有初始化好))

15.[※※※※]runtime如何通过selector找到对应的IMP地址?(分别考虑类方法和实例方法)

(通过对象的isa指针,关于isa指针具体分析看上上两道题解答分析 (调度表存的selector 和 imp会进行绑定))

16.[※※※※]使用runtime Associate方法关联的对象,需要在主对象dealloc的时候释放么?

(不需要,当宿主对象释放的时会根据指定的内存管理策略处理关联的对象)

17.[※※※※※]objc中的类方法和实例方法有什么本质区别和联系?

(类方法是是静态方法在程序创运行的时候已经创建并且以后创建的实例和类都可以直接调用并且通用的,而实例方法要实例创建好的前提才创建并且每个实例方法都是独立的)

18.[※※※※※]_objc_msgForward函数是做什么的,直接调用它将会发生什么?

(当一个对象调用某方法的时候如果该类没有实现那么objc_msgForward就会把该消息转发(此时会检查该类是对运行时做了处理,如果现实了resolveInstanceMethod:和 methodSignatureForSelector:

会调用该方法

)给父类处理依次向上。直接调用将crash)

19.[※※※※※]runtime如何实现weak变量的自动置nil?

(在创建weak类型对象的时候objc会把该对象与一个地址(int whc = 0 ;whc的地址)绑定存在hash表中,当weak对象引用计数为0那么weak对象调用dealloc方法,在该方法里会

调用objc_clear_deallocating 找到运行时weak对象hash表并且获取该对象赋值为nil同时从weak对象的hash表中删除

)

20.[※※※※※]能否向编译后得到的类中增加实例变量?能否向运行时创建的类中添加实例变量?为什么?

(可以,可以,通过class_copyIvarList 可以获取运行时该类当前属性名称列表,通过class_addProperty方法可以在运行时动态想类中添加属性)

21.[※※※]runloop和线程有什么关系?

(首先每个线程都会有一个自己的runloop,线程一般不是单一运行从起点到终点就完了往往会回来处理其他任务,例如我们经常使用http异步请求,我们在进行http异步请求的时候系统会创建一个线程并且把网络请求事件加入到runloop中,当有数据接收的时候runloop会监听到从而通知外面接收存储显示等操作,总结runloop就是线程的一个事件循环调度块,当该线程有事件发生时runloop会捕捉到并通知该线程)

22.[※※※]runloop的mode作用是什么?

(runloop 的mode是runloop在线程中的运作模式,有如下几种运作模式:

NSDefaultRunLoopMode 描述:默认模式中几乎包含了所有输入源(NSConnection除外),一般情况下应使用此模式.

NSConnectionReplyMode 描述:处理NSConnection对象相关事件,系统内部使用,用户基本不会使用。

NSModalPanelRunLoopMode 描述:处理modal panels事件。

UITrackingRunLoopMode 描述:在拖动loop或其他user interface tracking loops时处于此种模式下,在此模式下会限制输入事件的处理。例如,当手指按住UITableView拖动时就会处于此模式。

NSRunLoopCommonModes 描述:这是一个伪模式,其为一组run loop mode的集合,将输入源加入此模式意味着在Common Modes中包含的所有模式下都可以处理。默认情况下Common Modes包含default modes,modal modes,event Tracking modes.可使用CFRunLoopAddCommonMode方法想Common Modes中添加自定义modes。

)

23.[※※※※]以+ scheduledTimerWithTimeInterval…的方式触发的timer,在滑动页面上的列表时,timer会暂定回调,为什么?如何解决?

(因为+ scheduledTimerWithTimeInterval创建的timer加入到runloop中是NSDefaultRunLoopMode

模式(该模式描叙看上题分析),而列表滑动事件在runloop中是UITrackingRunLoopMode模式而runloop同时只支持一种模式运行所以滑动列表时timer不处理。

要解决这个问题我们可以把timer以NSRunLoopCommonModes模式加入(该模式解析看上题)。

)

24.[※※※※※]猜想runloop内部是如何实现的?

(do{

if(有事件处理){

获取当前事件模式,结束其他事件模式

处理该事件

}

}while(线程是否结束))

25.[※]objc使用什么机制管理对象内存?

(引用计数方式管理对象内存)

26.[※※※※]ARC通过什么方式帮助开发者管理内存?

(arc模式下编译器会自动插入retian 和 release代码)

27.[※※※※]不手动指定autoreleasepool的前提下,一个autorealese对象在什么时刻释放?(比如在一个vc的viewDidLoad中创建)

(autorealese对象会在其作用域结束的时候当前由autoreleasepool释放 viewDidLoad中创建的对象会在执行该方法结束的时候释放)

28.[※※※※]BAD_ACCESS在什么情况下出现?

(访问一个野指针和死循环的时候)

29.[※※※※※]苹果是如何实现autoreleasepool的?

(用队列实现的操作该队列有如下函数:

objc_autoreleasepoolPush,objc_autoreleasepoolPop,objc_autorealease

)

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

(某个对象objc1引用了某个对象objc2的block而objc2对象的block也引用了objc1(block里使用时对象objc1引用计数会自动加一是导致循环引用根本原因),所以发生循环引用

声明一个__weak 类型的objc1,在objc2的block里用__weak 类型的objc1(__weak类型objc1对象引用计数不会加一))

31.[※※]在block内如何修改block外部变量?

(声明变量对__block 类型)

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

(UIView动画block不用考虑,无论是系统还是自定义实例只要有这样情况才考虑循环引用:你中有我,我中有你强引用 如单例通知中心NSNotificationCenter)

33.[※※]GCD的队列(dispatch_queue_t)分哪两种类型?

(串行和并发队列)

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

(实现代码
dispath_queue_t queue = dispatch_get_global_queue(0,0);

dispatch_group_t group = dispatch_group_create();

for(NSString * strUrl in _strUrlArr){

  dispatch_group_async(group,queue,^{      下载若干图片存储到array  });

}

dispatch_group_notify(group,queue,^{对array中的图片进行合成处理});

35.[※※※※]dispatch_barrier_async的作用是什么?

(主要应用在并发队列中,主要是保证所有异步块有序进行barrie异步块会进行耗时任务并且其他异步块会等到barrie块完成某些任务再继续执行)

36.[※※※※※]苹果为什么要废弃dispatch_get_current_queue?

(同步阻塞操作造成死锁)

37.[※※※※※]以下代码运行结果如何?

- (void)viewDidLoad{    [super viewDidLoad];    NSLog(@"1");    dispatch_sync(dispatch_get_main_queue(), ^{        NSLog(@"2");    });    NSLog(@"3");}

(1,主线程死锁)

38.[※※]addObserver:forKeyPath:options:context:各个参数的作用分别是什么,observer中需要实现哪个方法才能获得KVO回调?

(第一个参数:接收监听通知的对象

第二个参数:要监听的路径(如属性@property NSString * whc;该参数可以为@“whc”)状态变化

第三个参数:监听选项

NSKeyValueObservingOptionNew //监听新值

NSKeyValueObservingOptionOld //监听旧值

NSKeyValueObservingOptionInitial // 监听新值,但初始化会调用一次
NSKeyValueObservingOptionPrior //监听新值和旧值 会分别调用
第四个参数:上下文可以带入一些参数可以是任意类型强转就可以了。

)

39.[※※※]如何手动触发一个value的KVO

(自己强制调用wilChangeValueForKey:和didChangeValueForKey:方法,并实现+ (BOOL)automaticallyNotifiesObserversForLComponent;

  • (BOOL)automaticallyNotifiesObserversForLComponent{
    return NO;//关闭自动触发
    }
  • (void)setWhc:(double)whc{
    [self willChangeValueForKey:@”whc”];
    _whc = whc;
    [self didChangeValueForKey:@”whc”];
    }

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

(foo)

41.[※※※※]KVC的keyPath中的集合运算符如何使用?

(比较常用的集合运算符有@agv ,@count , @min ,@max , @sum

@interface WHC:NSObject

@property NSNumber * age;

@end

使用实例:NSArray * whcArr ; (whcArr存都是WHC对象)

NSnumber * agvWhc = [whcArr valueForKeyPath:@“@agv.age”];//获取集合对象whcArr里所有whc对象的平均年龄

)

42.[※※※※]KVC和KVO的keyPath一定是属性么?

(还可以是以set开头并带有一个参数无返回值的方法)

43.[※※※※※]如何关闭默认的KVO的默认实现,并进入自定义的KVO实现?

(请参考上面 “如果手动触发一个kvo” 题目解答分析)

44.[※※※※※]apple用什么方式实现对一个对象的KVO?

(当某个类实例被观察时系统会自动创建该类的一个派生类并且重写被观察的setter方法,同时实例内存模型中isa指针会重新指向派生类,此时当

调用实例的setter方法时会先调用派生类的setter方法然后再调用原来setter方法并在派生类setter方法中增加will/didChangeValueForkey:方法,这两个will和did

方法会通知外面相应状态改变。

分析中的派生类重写父类的setter方法大概是这样的:

-(void)setWhc:(int)whc{  [self willChangeValueForkey:@“whc”]; //改变之前通知  [super setWhc:whc];  //调用父类setter方法[self didChangeValueForkey:@“whc”]; //改变之后通知} 

)

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

(其实我想问的是为什么不能设置为weak?,任何地方只要不想拥有其他对象的强引用就不需要设置为strong,例如在xib上面我拖上去仅仅只是添加在view上面而不是VC本身所以vc没有必要对view的subview进行strong引用)

46.[※※※※※]IB中User Defined Runtime Attributes如何使用?

(在xib或者sb面板上添加默认没有的属性和值)

47.[※※※]如何调试BAD_ACCESS错误

(开启僵尸模式,并添加所有异常设置)

48.[※※※]lldb(gdb)常用的调试命令?

(p po打印对象值命令, bt 显示详细错误信息,n 断点调试下一步)

//扩展题目

49.什么是隐试和显示动画特点举例子说明?

50.控制器的loadView在有xib和没有xib时有什么区别应该注意什么?

51.如何实现两个列表一起滑动(当滚动其中一个另个也一起动)?

52.如何用一个UIButton实现图片文字上下居中显示(图片在上文字在下)?

53.whcArr可变数组存储whc对象,而whc对象有个属性年龄,如何实现对这个whcArr依据whc对象年龄进行倒序排序?

54.UITableView上的Cell图文混排时再不用第三方开源帮助下如何自己实现,说明实现原理?

55.oc如何实现多继承?

56.category 和 extension有什么区别?

57.category中如何添加属性?

58.众多下拉刷新开源代码核心实现原理是什么?

59.在有UITabbarController和UINavigationController情况下如何控制每个控制器的横竖屏显示?

60.layer是什么?

61.view和layer有什么关联?

62.如何实现渐变动态的绘制图形(说原理)?

63.当向一个view添加subview时如果subview添加到了view范围之外为什么依然可以显示?

64.什么是window对象和view有什么关联?

65.什么是keyWindow?

66.window和keyWindow有什么区别?

67.iOS事件消息分发机制是?

68.在根视图view中如何截拦subview 按钮的点击事件?

69.qq的app中tabbaritem上的可以动画拖拽消息气泡如何实现的原理(主要针对触摸消息冲突层面说明)?

0 0