17.3.24备忘录

2017-03-24  本文已影响9人  cdd48b9d36e0

1、为什么通知必须在dealloc里移除(02-UITableview(4))

一个addServer会在通知中心里产生一个指针指向该通知的观察者,如果dealloc的时候不移除,那么只要通知被再次触发通知中心就会根据这个指针也就是地址去给这个观察者发送消息,这其实就是操作野指针了

2、setValuesForKeysWithDictionary的实现原理(03-UI进阶(1))

  1. 遍历所有的key得到key的值name
  2. 去模型查找有没有setName:方法,有的话直接赋值 setName:name
  3. 假如没有该set方法,就去模型中查找有没有_name属性,有的话_name = name
  4. 假如没有_name,就去模型中查找有没有name属性
  5. 假如还是没有,就会报错

第二步setName:这里只要求名字一样,后面的参数类型是可以替换的(0609-UIPickerView键盘处理)

3、一个IOS程序启动步骤(03-UI进阶(2))

4、事件的传递(03-UI进阶(5))

点击一个控件让他响应指定的操作,这个事件会经历产生、传递、响应三个过程:

 - (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
{
    // 调用系统的做法去寻找最合适的view,返回最合适的view
    return [super hitTest:point withEvent:event];
}

实际项目中,需求通常是要点击一个控件让另外一个控件响应,这时候就需要重写hitTest方法。重写分为三步,第一步是判断自己能不能响应事件,包括打开用户交互、hidden、alpha三个方面;第二步是触摸点在不在自己身上;第三部是倒序遍历子控件,重复前两步,直到找到最合适的View,这是一个递归的过程。

 - (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
{
//    NSLog(@"%@--hitTest",[self class]);
//    return [super hitTest:point withEvent:event];
    
    NSLog(@"%@--%@",[self class],NSStringFromCGPoint(point));
    // 1.判断当前控件能否接收事件
    if (self.userInteractionEnabled == NO || self.hidden == YES || self.alpha <= 0.01) return nil;
    
    // 2. 判断点在不在当前控件
    if ([self pointInside:point withEvent:event] == NO) return nil;
    
    // 3.从后往前遍历自己的子控件
    NSInteger count = self.subviews.count;
    
    for (NSInteger i = count - 1; i >= 0; i--) {
        UIView *childView = self.subviews[i];
        
        // 把当前控件上的坐标系转换成子控件上的坐标系
     CGPoint childP = [self convertPoint:point toView:childView];
        
       UIView *fitView = [childView hitTest:childP withEvent:event];
        if (fitView) { // 寻找到最合适的view
            return fitView;
        }  
    }
    // 循环结束,表示没有比自己更合适的view
    return self;
}

5、环信(16-环信(总结))

登录注册模块要注意的:自动登录、自动联网、自动连服务器
好友管理模块:获取、添加、删除好友(包括数据库结构,第一次登录或者改变好友后从服务器拉取好友保存到数据库,以后每次都是从本地数据库拉取好友列表)

上一篇下一篇

猜你喜欢

热点阅读