记 static 帮我解决的问题

先说遇到的问题,
项目的业务逻辑中,有巡检的单子派发到某个人之后,需要先进行开始巡检,然后逐项巡检,最后提交保存。
问题出现在,在开始巡检的时候,速度会非常之慢。主要表现在数据库有50万条数据(单子)。每一个巡检项,从模板表写入到巡检录入中间表的时候,打印日志显示4秒平均一个。然而每天会有100+的单子,每个单子30~40项不等的巡检项,可想而知会有多慢。
受不了当前的速度,就开始打断点查找原因
最终定位问题在下面这个方法:

+ (NSString *)getInspectionContensID {
    
    NSString *uuidString = [WJHUUIDManager getUUIDString];
    
    NSString *sql = [NSString stringWithFormat:@" SELECT ID FROM om_on_inspection_entry_mg "];
    NSMutableArray *uuidArray = [[WJHDBManager sharedManager] selectWithSql:sql andOneArr:@[@"ID"]];
    
    if (uuidArray.count == 0) {
        return uuidString;
    }else {
        
        for (NSArray *arr in uuidArray) {
            if ([[[arr firstObject] objectForKey:@"ID"] isEqualToString:uuidString]) {
               return  [WJHUUIDManager getInspectionContensID];
            }else {
                return uuidString;
            }
        }
    }    
}

每一个巡检项都需要一个UUID来唯一确定,为了不和已有的UUID重复,这里就是来防止重复的。
显然问题是很明显的,50万级别的数据,每次都去数据库中查一遍,然后再作比对,很明显,时间都浪费在查询上了。下面,就开始介绍 static如何帮助到我的。
首先,static 静态变量:

1.作用于变量:
用static声明局部变量时,则改变变量的存储方式(生命期),使变量成为静态的局部变量,即编译时就为变量分配内存,直到程序退出才释放存储单元。这样,使得该局部变量有记忆功能,可以记忆上次的数据,不过由于仍是局部变量,因而只能在代码块内部使用(作用域不变)

用static声明外部变量-------外部变量指在所有代码块{}之外定义的变量,它缺省为静态变量,编译时分配内存,程序结束时释放内存单元。
同时 其作用域很广,整个文件都有效甚至别的文件也能引用它。为了限制某些外部变量的作用域,使其只在本文件中有效,而不能被其他文件引用,
可以用static 关键字对其作出声明。

 静态变量的优点:
    1、节省内存。静态变量只存储一处,但供所有对象使用。
    2、它的值是可以更新的。
    3、可提高时间效率。只要某个对象对静态变量更新一次,所有的对象都能访问更新后的值。

另:

2.作用于函数:使用static用于函数定义时,对函数的连接方式产生影响,使得函数只在本文件内部有效,对其他文件是不可见的。这样的函数又叫作静态函数。使用静态函数的好处是,不用担心与其他文件的同名函数产生干扰,另外也是对函数本身的一种保护机制。如果想要其他文件可以引用本地函数,则要在函数定义时使用关键字extern,表示该函数是外部函数,可供其他文件调用。另外在要引用别的文件中定义的外部函数的文件中,使用extern声明要用的外部函数即可。

以上是对其的解释,总之,现在我优化的方向就是,这些巡检项的UUID我只查询一次就存储起来,之后,直接拿来用,这样速度可定就很快了,而且生成了新的就及时的添加到新的存储中。
如此,便优化到了下面

static NSMutableArray *inspectionUUID;

@implementation WJHUUIDManager



+ (NSMutableArray *)readLocalFile {
    
    static dispatch_once_t predicate;
    dispatch_once(&predicate, ^{
        
        NSString *sql = [NSString stringWithFormat:@" SELECT ID FROM om_on_inspection_entry_mg "];
        inspectionUUID = [[WJHDBManager sharedManager] selectWithSql:sql andOneArr:@[@"ID"]];
    });
    
    return inspectionUUID;
}

+ (NSString *)getInspectionContensIDWithContentID:(NSMutableArray *)contentID {
    
    NSString *uuidString = [WJHUUIDManager getUUIDString];
    
    
    if (contentID.count == 0) {
        
        inspectionUUID = [WJHUUIDManager readLocalFile];
        if (inspectionUUID.count == 0) {
            
            return uuidString;
        }else {
            
            if ([inspectionUUID containsObject:uuidString]) {
                
                [inspectionUUID addObject:uuidString];
                return [WJHUUIDManager getInspectionContensIDWithContentID:inspectionUUID];
            }else {
                
                return uuidString;
            }
            
        }
    }else {
        
        if ([contentID containsObject:uuidString]) {
            
            [contentID addObject:uuidString];

            return [WJHUUIDManager getInspectionContensIDWithContentID:contentID];
        }else {
            
            return uuidString;
        }
    }
   
}

@end

这样,就实现了,只查询一次所有的巡检项的UUID,并将其存储起来,之后的直接拿来比较就好。
最后,速度上的提升是这样的。 同一个巡检单,之前是3分钟,优化之后,也就6s吧。哈哈,问题解决了。

你可能感兴趣的:(记 static 帮我解决的问题)