美文网首页
OC小总结

OC小总结

作者: CoderHG | 来源:发表于2017-12-26 18:12 被阅读76次

    一、比较大小

    一个枚举

    typedef NS_ENUM(NSInteger, NSComparisonResult) {
      NSOrderedAscending = -1L, 
      NSOrderedSame,
      NSOrderedDescending
    };
    

    这个枚举, 主要用于NSString的这个方法:

    - (NSComparisonResult)compare:(NSString *)string;
    

    其中也有一个NSNumber的同样方法,用法一致。

    一般应该怎么使用呢?看下面的例子:

    // str1 与 str2 都是字符串
    NSComparisonResult cResult = [str1 compare:str2];
    switch (cResult) {
        case NSOrderedAscending:
            {
                NSLog(@"str1 大于 str2");
            }
            break;
        case NSOrderedSame:
        {
            NSLog(@"str1 等于 str2");
        }
            break;
        case NSOrderedDescending:
        {
            NSLog(@"str1 小于 str2");
        }
            break;
            
        default:
            break;
    }
    

    二、排序

    排序,往往需要一种规则, 比如大小的比较,排序都是出现在数组中。

    一个简单的字符串数组的排序

    NSArray* arr = @[@"1", @"3", @"2"];
    NSLog(@"原始顺序 \n%@", arr);
    {
        /** 原始顺序
        (
         1,
         3,
         2
         )
         */
    }
    arr = [arr sortedArrayUsingComparator:^NSComparisonResult(id  _Nonnull obj1, id  _Nonnull obj2) {
        // 这是升序, 如果需要降序, 将 obj1 与 obj2换个位置就可以了
        return [obj1 compare:obj2];
    }];
    
    NSLog(@"排序后 \n%@", arr);
    {
        /** 排序后
        (
         1,
         2,
         3
         )
        */
    }
    

    还有一种情况是, 数组中的元素是一个模型, 需要根据其中的一个字段来进行排序. 比如有一个Person集合的数据, 需要根据年龄进行排序.

    这个Person类的定义如下:
    .h文件

    #import <Foundation/Foundation.h>
    
    @interface Person : NSObject
    
    /** 名字 */
    @property (nonatomic, copy) NSString* name;
    /** 年龄 */
    @property (nonatomic, copy) NSString* age;
    
    @end
    

    .m文件

    #import "Person.h"
    
    @implementation Person
    
    - (NSString *)description {
        return [NSString stringWithFormat:@"name: %@, age: %@", self.name, self.age];
    }
    
    @end
    

    例子:

    
    Person* p1 = [[Person alloc] init];
    p1.name = @"p1";
    p1.age = @"22";
    
    Person* p2 = [[Person alloc] init];
    p2.name = @"p2";
    p2.age = @"23";
    
    Person* p3 = [[Person alloc] init];
    p3.name = @"p3";
    p3.age = @"21";
    
    
    NSArray* persons = @[p1, p2, p3];
    NSLog(@"原始顺序 \n%@", persons);
    {
        /** 原始顺序
        (
         "name: p1, age: 22",
         "name: p2, age: 23",
         "name: p3, age: 21"
         )
         */
    
    }
    
    persons = [persons sortedArrayUsingComparator:^NSComparisonResult(Person* obj1, Person* obj2) {
        // 根据年龄实现升序排序
        return [obj1.age compare:obj2.age];
    }];
    
    NSLog(@"排序后 \n%@", persons);
    {
        /** 排序后
        (
         "name: p3, age: 21",
         "name: p1, age: 22",
         "name: p2, age: 23"
         )
         */
    }
    

    三、查找数据

    很多时候, 就需要在数组中去查找我们需要的数据, 就拿上面的** Person**来举个例子:

    Person* p1 = [[Person alloc] init];
    p1.name = @"p1";
    p1.age = @"22";
    
    Person* p2 = [[Person alloc] init];
    p2.name = @"p2";
    p2.age = @"23";
    
    Person* p3 = [[Person alloc] init];
    p3.name = @"p3";
    p3.age = @"21";
    
    Person* p4 = [[Person alloc] init];
    p4.name = @"p1";
    p4.age = @"25";
        
    
    NSArray* persons = @[p1, p2, p3, p4];
    
    // 找出所有 name 是 p1 的人
    NSString* name = @"p1";
    NSPredicate* predicate = [NSPredicate predicateWithFormat:@"SELF.name CONTAINS[c]%@", name];
    
    NSArray* filtereds = [persons filteredArrayUsingPredicate:predicate];
    
    if (filtereds.count > 0) {
        NSLog(@"找到了 \n%@", filtereds);
        {
            /** 找到了
            (
             "name: p1, age: 22",
             "name: p1, age: 25"
             )
             */
        }
    } else {
        NSLog(@"没有找到");
    }
    

    这里使用了iOS的** NSPredicate**, 这东西很强大的, 可以参考这篇很全很经典的文章:iOS中的谓词(NSPredicate)使用

    四、isEqual:的用法

    在一个数组中查找某个数据, 除了使用上面说到的NSPredicate, 还有另一个方法, 但是最好的方式, 还是使用NSPredicate. 那就是重写isEqual:方法.

    - (BOOL)isEqual:(Person*)object {
        // 如果name相等, 则说明是同一个人
        return [self.name isEqual:object.name];
    }
    

    看一下实验:

    Person* p1 = [[Person alloc] init];
    p1.name = @"p1";
    p1.age = @"22";
    
    Person* p2 = [[Person alloc] init];
    p2.name = @"p2";
    p2.age = @"23";
    
    NSArray* persons = @[p1, p2];
    
    
    Person* p = [[Person alloc] init];
    p.name = @"p1";
    p.age = @"22";
    
    if ([persons containsObject:p]) {
        // 会打印这句话的
        NSLog(@"p 在 persons 中");
    } else {
        NSLog(@"p 不在 persons 中");
    }
    

    这种方式其实很low, 知道能这样做就OK.只需要知道containsObject:方法会调用isEqual:即可.

    五、unsafe_unretained 与 weak

    • 都是弱指针类型
    • weak指向的对象销毁了, 当前指针制动变成nil。 则unsafe_unretained不会,所以会导致坏地址访问闪退。

    有一个关于NSNotificationCenter的例子:为什么在iOS9之前一定要对observer进行remove, 而之后可以不需要呢? 就是因为在NSNotificationCenter中对observer的引用一个是unsafe_unretained, 一个是weak

    关于这个点,推荐一个很不错的文章:关于__autoreleasing,你真的懂了吗?

    六、关于死锁

    在主队列中回到主队列, 这样的:

       dispatch_sync(dispatch_get_main_queue(), ^{
           NSLog(@"dispatch_get_main_queue");
       });
    

    运行是这样的:


    image.png

    七、NSTimer注意事项

    • 以timer开头的类方法创建的定时器需要手动添加Runloop,通过scheduledTimer开头的则不需要。
    • 记得在不用的时候, 以这样的方式关闭定时器:
     [_timer invalidate];  
      _timer = nil;
    

    相关文章

      网友评论

          本文标题:OC小总结

          本文链接:https://www.haomeiwen.com/subject/mpljgxtx.html