开发Tip之一

iOS 开发Tip之一

  1. 获取当前执行函数的名字

    1
    NSStringFromSelector(_cmd)

    _cmd 可以拿到当前函数的Selector

  2. 数组的最大值、最小值、求和快捷操作

    1
    2
    3
    [@[@(1), @(2), @(3)] valueForKeyPath:@"@ max.self "]; // 最大值
    [@[@(1), @(2), @(3)] valueForKeyPath:@"@ min.self "]; // 最小值
    [@[@(1), @(2), @(3)] valueForKeyPath:@"@ sum.self "]; // 求和
  3. 几种空指针

    1
    2
    3
    4
    NULL // C和C++里面的空地址
    nil // OC对象空指针
    NSNull // 表示为空的对象
    Nil // 类对象空指针
  4. 结构体快捷构建

    1
    CGRect visibleRect = (CGRect){.origin = {100,100}, .size = self.view.frame.size};
  5. 给协议添加属性

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    // step 1 添加一个属性申明
    @property (nonatomic, strong) NSString * object;

    // step 2 添加一个静态属性作为标识(静态属性地址唯一)
    static char * objectIdentifier;

    // step 3 添加get方法
    - (NSString *)object {
    return objc_getAssociatedObject(self, &objectIdentifier);
    }

    // step 4 添加set方法
    - (void)setObject:(NSString *)object {
    objc_setAssociatedObject(self, &objectIdentifier, object, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
    }

    不需要为了KVO而手动调用 willChangeValueForKey:, didChangeValueForKey: 方法,这两个方法底层会自动调用,可以正常KVO

  6. __block关键字添加的属性要小心初始值

    1
    2
    3
    4
    5
    6
    7
    8
    9
    __block BOOL isGoodDay;

    dispatch_async(dispatch_get_main_queue(), ^{
    if (isGoodDay) {
    NSLog(@"today is good day");
    }
    });

    // isGoodDay在某些机型上有可能是YES

    解决办法是所有的属性,申明的时候必须初始化值

  7. 不要给NSString设置strong修饰符

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    @property (nonatomic, strong) NSString * name;

    NSMutableString * str = [NSMutableString stringWithFormat:@"jack"];
    self.name = str;

    NSLog(@"name is %@", self.name);

    [str appendString:@" tome"];

    NSLog(@"name is %@", self.name);

    // 输出:
    /*
    2017-12-12 22:49:26.221790+0800 TouchDemo[66149:20611122] name is jack
    2017-12-12 22:49:26.221890+0800 TouchDemo[66149:20611122] name is jack tome
    */

    类型定为NSString,通常来说是不希望值改变的,但事实上值改变了,如果真的需要mutable的特性,最好把类型定为NSMutableString,否则使用copy修饰符

  8. 暂停和恢复UIView动画

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    - (void)pauseAction:(id)sender {
    CFTimeInterval time = [self.animView.layer convertTime:CACurrentMediaTime() fromLayer:nil];
    self.animView.layer.timeOffset = time;
    self.animView.layer.speed = 0.0f;
    }

    - (void)resumeAction:(id)sender {
    if (self.animView.layer.speed > 0.0f) {
    return ;
    }
    CFTimeInterval pauseTime = self.animView.layer.timeOffset;
    CFTimeInterval timeSincePause = CACurrentMediaTime() - pauseTime;
    self.animView.layer.timeOffset = 0;
    self.animView.layer.beginTime = timeSincePause;
    self.animView.layer.speed = 1;
    }
  9. 去掉UITableView因为数据不够多出来的Cell和横线

    1
    self.tableView.footerView = [UIView new];
  10. 点击任意位置收起键盘

1
2
3
4
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
[super touchesBegan:touches withEvent:event];
[self.view endEditing:YES];
}

需要设置view的userInteractionEnabled为YES(默认就是YES)

  1. UIButton 对齐

    UIButton 默认是垂直、横向居中对齐的,有时候达不到我们的要求,这时候可以通过设置 contentHorizontalAlignmentcontentVerticalAlignment 属性来改变对齐方式

    1
    button.contentHorizontalAlignment = UIControlContentHorizontalAlignmentRight;