Skip to content
gracenamucuo edited this page Mar 10, 2019 · 38 revisions

iOS开发

用来记录本仓库的知识点,加上自己的理解。如有错误,欢迎指出。


设计模式


正常的方法调用performSelector

两者最终走的流程都是一样的,但是就在写代码时,正常的方法调用,必须有声明,即便没有实现,
也需要有声明,否则Xcode编译报错,因此必须要引入对应的头文件,
而performSelector则可以,直接调用,可以不用声明,所以可以不用引入对应的头文件,可以做到一定程度的解耦。
但是如果没有实现对应的方法的话,最后在运行的时候也是会报错的。

不要在初始化方法和dealloc方法中调用setter或getter方法

子类重写了父类的setter方法,在父类的init方法中调用了setter方法,在初始化子类的时候,父类init中setter方法走的是子类重写的setter方法,此时,子类中的init方法还没有执行,即子类还没有初始化完成,就调用子类的方法,会出现未知的bug。 同理,在父类的dealloc中调用存取方法时,如果子类中重写了该存取方法,执行父类的dealloc中的存取方法时,会调用子类的存取方法,此时子类已经释放了,可能会出现问题。


load VS initialize

+load + initialize
调用时机 类被加载到runtime时 收到第一条消息时,如果没收到消息,就不会调用
调用顺序 父类->子类->分类 父类->子类
调用次数 1次 可能会多次
是否需要显示的调用父类实现
是否沿用父类的实现
分类中的实现 类和分类都执行 覆盖类中的方法,只执行分类中的实现
//保证initialize方法只执行一次
 + (void)initialize {
  if (self == [ClassName self]) {//当为该类本身的时候执行
    // ... do the initialization ...
  }
}

block和delegate的使用比较

针对结果的行为用block;注重过程状态的的行为用delegate


手势的tips

 CGPoint p1 = [gr locationInView:self.view];
p1是手势落到所在view上的相对于view的坐标点。
 CGPoint p2 = [gr translationInView:self.view];
p2是手势滑动一下之后到的点相对于落在view上时那一点(p1)的相对坐标点。

nil、Nil、NULL、NSNull的区别

  • nil:指向一个对象的空指针。

NSObject *obj = [NSObject new]; obj = nil; id obj1 = [NSObject new]; obj1 = nil;

  • Nil:指向一个类对象的空指针,表示对类对象进行清空赋值。

Class cls = [Person class]; cls = Nil;

  • NULL:指向其他类型(如:基本类型、C类型)的空指针, 对非对象指针赋空值,C语言中防止野指针.

int a = 10; int *p = &a; p = NULL;

  • NSNull:是一种类型,表示空值的对象.

NSNull *nullObj = [[NSNull alloc]init];

NSNull *nullObj = [NSNull null];


搜索关键字匹配字符串中的所有位置(NSRange)

NSString的分类
- (NSArray *)arrayOfRangesWithKey:(NSString *)key
{
    if (![self containsString:key]) {
        return @[];
    }
    NSMutableArray *array = [NSMutableArray array];
    NSString *str = [self copy];
    NSInteger location = 0;
    while (str.length > 0 && [str containsString:key]) {
        NSRange range = [str rangeOfString:key];
        str = [str substringFromIndex:(range.location + range.length)];
        location += range.location + range.length;
        range.location = location - key.length;
        NSValue *value = [NSValue valueWithRange:range];
        [array addObject:value];
    }
    return array;
}



寻找找界面上两个视图的最近父视图

- (UIView *)findNearestSuperViewFrom:(UIView *)aView to:(UIView *)bView {
    
    NSArray *aSuperViews = [self superViewsForView:aView];
    NSArray *bSuperViews = [self superViewsForView:bView];
    NSSet *set = [NSSet setWithArray:bSuperViews];
    for (UIView *aSuperView in aSuperViews) {
        if ([set containsObject:aSuperView]) {
            return aSuperView;
        }
    }
    return nil;
}

- (NSArray<UIView *> *)superViewsForView:(UIView *)subView {
    NSMutableArray *views = [NSMutableArray array];
    subView = subView.superview;
    while (subView != nil) {
        [views addObject:subView];
        subView = subView.superview;
    }
    return [views copy];
}