面试题

响应链:

用户点击屏幕产生事件 -> UIApplication 开始事件分发
-> UIWindow-> Subviews
UIWindow的子视图会内部递归调用

- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event

如果上面的方法返回视图就会调用这个方法

- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event {
  • 当view的userInteractionEnabled为NO、hidden为YES或alpha<=0.1时,也不会打印pointInside方法。因此可以推断出在hitTest方法内部会判断如果这些条件一个成立则会返回nil,也不会调用pointInside方法。
  • pointInside只是在执行hitTest时,会在hitTest内部调用的一个方法。也就是说pointInside是hitTest的辅助方法。
  • 通过重写目标控件的pointInside: withEvent:方法可以扩大响应范围
- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event {
    
    NSLog(@"%@ -- pointInside",self.class);
    CGRect bounds = self.bounds;
    //若原热区小于200x200,则放大热区,否则保持原大小不变
    //一般热区范围为40x40 ,此处200是为了便于检测
    CGFloat widthDelta = MAX(200 - bounds.size.width, 0);
    CGFloat heightDelta = MAX(200 - bounds.size.height, 0);
    bounds = CGRectInset(bounds, -0.5 * widthDelta, -0.5 * heightDelta);
    return CGRectContainsPoint(bounds, point);
}

响应链事件是由上至下的;触摸事件是由由下至上的;

分类关联对象

  • objc_setAssociatedObject(id object, const void *key, id value, objc_AssociationPolicy policy)函数
    1.系统用一个全局的AssociationsManager去管理一张全局的AssociationsHashMap表,表中key是disguised_ptr_t(由object转化而来),valueAssociationsHashMap
    2.AssociationsHashMapkey就是上面函数中的const void *key,而valueObjcAssociation
    3.ObjcAssociation 内包含着 policy,和具体的value
    原理图
    截屏2019-11-22上午11.23.05.png

    所以关联对象并不是放在了原来的对象里面,而是系统维护了一个全局的map用来存放每一个对象及其对应关联属性表格。

weak 如何自动置为nil

你可能感兴趣的:(面试题)