一,如何通过View找到其所在的Controller。
根据响应链去查找,响应链中的对象有View,Controller,Window,UIApplication,都是继承于UIResponder。
UIView和UIViewController的基类都是UIResponder,UIResponder用于处理事件响应。
1,首先,UIView 的 nextResponder指向它的 SuperView;如果 UIView 已经是其所在的 UIViewController 的 self.view,也就是top View,那么 UIView 的 nextResponder 就是 UIViewController;
所以UIViewController.view.nextResponder = UIViewController;
2,UIWindow 的 nextResponder 是 UIApplication;
3,UIApplication 的 nextResponder 是 AppDelegate;
//UIView类别中方法 -(UIViewController *)viewController{ UIViewController *viewController = nil; UIResponder *next = self.nextResponder; while (next) { if ([next isKindOfClass:[UIViewController class]]) { viewController = (UIViewController *)next; break; } next = next.nextResponder; } return viewController; }
二,给定一个排序数组,删除重复出现的元素,使得每个元素只出现一次,返回移除后数组的新长度,要求不是用额外数组空间,并且空间复杂度为O(1)下完成。
NSInteger array[] = {0,0,1,1,1,2,2,3,3,4}; NSInteger length=sizeof(array)/sizeof(array[0]); NSInteger k = 0; for (NSInteger i = 1; i < length; i++) { if(array[i] != array[k]){ k++; array[k] = array[i]; } } NSLog(@"%ld",k + 1); //K + 1就是去重后的元素 for(NSInteger j = 0 ; j < length ; j++ ){ printf("元素 - - %ld\n",(long)array[j]); }
空间复杂度为O(1),也就是当前计算方法时长应该是O(1),随着数据的增加,算法的使用空间不会增加,因为已经给定了当前数组的控件,不需要开辟别的。
三,以下代码会怎么执行,为什么?
@interface NSObject (Chain) + (void)runChainTest; @end @implementation NSObject (Chain) - (void)runChainTest { NSLog(@"runChainTest"); } @end - (void)viewDidLoad { [super viewDidLoad]; [NSObject runChainTest]; //objc_msgSend(objc_getClass("NSObject"),@selector(runChainTest)); }
NSObject -> 元类 寻找
元类 -> 他的父类父类(根元类) 寻找
根元类就是自己(NSObject)
那么NSObject对象的实例方法和类方法都是在NSObject中去寻找,所以发消息的NSObject就是当前NSObject的对象,直接调用了实例方法。
1,首先NSObject会在自己的元类的方法列表中去寻找此方法,如果没有找到;
2,那么就回去元类的父类,也就是根元类中去寻找此方法,NSObject的根元类找,也就是自己;
3,那么NSObject对象的实例方法和类方法都是在NSObject中去寻找,所以发消息的NSObject就是当前NSObject的对象,也就是NSObject是一个实例,会去调用它本身实例方法列表中注册的实例方法,也就是减号方法。
拓展:
方法只在.h中进行了声明,.m没有去实现,runtime是没有注册到当前的实例结构体中的方法列表中,所以runtime找不到此方法。
只有实现了方法才能被runtime找到,因为实现了的方法已经被注册到了实例结构体中的方法列表中。
分析:
+Method,调用者是类,调用方法存在元类结构体的方法列表中; -Method,调用者是实例,调用方法存在当前对象类的结构体方法列表中; +Method; 去NSObject的元类; +Method; 去NSObject的元类的父类(根元类)(指向自己NSObject); +Method; 又去NSObject的元类;
四,@synchronized与dispatch_once创建单例时的区别?
@synchronized会创建一个递归(recursive)互斥(mutex)的锁与 object参数进行关联。对当前绑定的对象进行了转换等递归操作,进行一系列的查询和创建工作,比较耗费系统资源。
dispatch_once,内部则使用了很多原子操作来替代锁,以及通过信号量来实现线程同步,而且有很多针对处理器优化的地方,甚至在if判断语句上也做了优化,使得其效率有很大的提升(相对于@synchronized来说)。
五,UIButton的继承关系是什么样的,他们的职能分别是什么?
继承关系:
UIButton -> UIControl -> UIView -> UIResponder -> NSObject
UIControl控制管理当前UIButton的各种事件,首先接受UIButton传递过来的事件,进行处理之后交付给UIResponder进行事件传递处理。
UIView管理和显示UIButton上的视图内容。
UIResponder去处理UIButton的事件,真正处理类。
六,atomic内部原理,那么它一定是安全的吗?
后续:
dispatch_once 和synchronized区别。
蒙版,水印,遮罩。
自动释放池和runloop的搭配关系。
UIButton的继承关系;
UIButton下UIControl和UIResponder,UIView之间的区别和职能。
单向链表倒数第K个数的实现。
weak底层原理
自动释放池和runloop的搭配关系。
@syncronized底层原理。