那些年遇到的坑

作者: yuanxy 分类: 开发 发布时间: 2017-08-11 01:03
  • 扩大按钮的点击范围 参考
  - (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent*)event
  {
      CGRect bounds = self.bounds;
      //若原热区小于44x44,则放大热区,否则保持原大小不变
      CGFloat widthDelta = MAX(44.0 - bounds.size.width, 0);
      CGFloat heightDelta = MAX(44.0 - bounds.size.height, 0);
      bounds = CGRectInset(bounds, -0.5 * widthDelta, -0.5 * heightDelta);
      return CGRectContainsPoint(bounds, point);
  }
  • 多线程同步问题造成的Crash 这个其实还蛮常见的, 尤其是在多线程泛滥使用的今天…你可以使用多线程, 但你要知道保护它呀, 哈哈. 对于数据源或model类一定要注意多线程同时访问的情况, 我个人比较喜欢用GCD的串行队列来同步线程.
  • Observer的移除 现在的代码里面很多需要用到Observer, 根据被观察对象的状态来相应的Update UI或者执行某个操作. 注册observer很简单, 但是移除的时候就出问题了, 要么是忘记移除observer了, 要么是移除的时机不对. 如果某个被观察对象已经被释放了, observer还在, 那结果只能是crash了, 所以切记至少在dealloc里面移除一下observer…
  • NSArray, NSDictionary成员的判空保护 在addObject或insertObject到NSArray或者NSDictionary时最好加一下判空保护, 尤其是网络相关的逻辑, 如果网络返回为空(jason解析出来为空), 但你还是毅然决然的add到array里面, 那么… 最后一点就是commit代码之前一定要保证木有warning, 木有内存泄露, 确保都OK之后再上传代码. 其实很简单, 上传代码之前Command + Shift + B静态分析一下, 看看有木有什么issue…
  • Block的循环引用问题 Block确实是个好东西, 但是用起来一定要注意循环引用的问题, 否则一不小心你就会发现, Oh My God, 我的dealloc肿木不走了…
  __weak typeof(self) weakSelf = self;
  dispatch_block_t block = ^{
    [weakSelf doSomething]; // weakSelf != nil
    // preemption, weakSelf turned nil
    [weakSelf doSomethingElse]; // weakSelf == nil
  };

如此在上面定义一个weakSelf, 然后在block体里面使用该weakSelf就可以避免循环引用的问题. 那么问题来了…是不是这样就完全木有问题了? 很不幸, 答案是NO, 还是有问题。问题是block体里面的self是weak的, 所以就有可能在某一个时段self已经被释放了, 这时block体里面再使用self那就是nil, 然后…然后就悲剧了…那么肿么办呢?

  __weak typeof(self) weakSelf = self;
  myObj.myBlock = ^{
      __strong typeof(self) strongSelf = weakSelf;
      if (strongSelf) {
         [strongSelf doSomething]; // strongSelf != nil
         // preemption, strongSelf still not nil
         [strongSelf doSomethingElse]; // strongSelf != nil
      }
      else {
         // Probably nothing...
         return;
      }
  };

解决方法很简单, 就是在block体内define一个strong的self, 然后执行的时候判断下self是否还在, 如果在就继续执行下面的操作, 否则return或抛出异常.

什么情况下会出现block里面self循环引用的问题? 这个问题问的好, 哈哈…简单来说就是双边引用, 如果block是self类的property (此时self已经retain了block), 然后在block内又引用了self, 这个情况下就肯定会循环引用了…

如果觉得我的文章对您有用,请随意赞赏。您的支持将鼓励我继续创作!

发表评论

您的电子邮箱地址不会被公开。 必填项已用*标注

标签云