Skip to main content
 首页 » 编程设计

swift之缓慢的 while 循环。 swift

2024年01月01日6652php

我对下面的代码有一些问题。当线路超过 10000 时,应用程序基本上会崩溃,或者至少不会响应或做任何事情。

label.text 可以毫无问题地输出整个文本文件。并且将整个 25000 行文件存储在 textArr -array 中是没有问题的。

但是当尝试对超过 10000 行的文件执行 while 循环时,它不会响应。

有什么解决办法的建议吗? :-)

    let path = NSBundle.mainBundle().pathForResource("thefile", ofType: "log") 
    var text = String(contentsOfFile: path!, encoding: NSUTF8StringEncoding, error: nil)! 
    var textArr = text.componentsSeparatedByString("\r\n") 
    var lines = textArr.count 
 
    var user_event=1 
    var user_state=1 
    var user_info=1 
    var user_devcom=1 
    var user_warning=1 
    var user_io=1 
    var user_useract=1 
    var user_error=1 
 
    class ViewController2: UIViewController { 
 
     override func viewDidLoad() { 
 
            label.font = UIFont(name: label.font.fontName, size: 8) 
 
            super.viewDidLoad() 
 
            var n=0 
 
            while n < lines{ 
 
                var rad: String = textArr[n] 
 
                if user_event == 1{ 
                   if rad.lowercaseString.rangeOfString("  event ") != nil{ 
                        label.text = "\(label.text!)\(rad)" 
                        label.text! += "\r\r" 
                    } 
                } 
 
                if user_state == 1{ 
                    if rad.lowercaseString.rangeOfString("  state ") != nil{ 
                        label.text = "\(label.text!)\(rad)" 
                        label.text! += "\r\r" 
                    } 
 
                } 
 
                if user_info == 1{ 
                    if rad.lowercaseString.rangeOfString("  info ") != nil{ 
                        label.text = "\(label.text!)\(rad)" 
                        label.text! += "\r\r" 
 
                    } 
                } 
 
                if user_devcom == 1{ 
                    if rad.lowercaseString.rangeOfString("  devcom ") != nil{ 
                        label.text = "\(label.text!)\(rad)" 
                        label.text! += "\r\r" 
                    } 
                } 
 
                if user_warning == 1{ 
                   if rad.lowercaseString.rangeOfString("  warning ") != nil{ 
                        label.text = "\(label.text!)\(rad)" 
                        label.text! += "\r\r" 
                    } 
                } 
 
                if user_io == 1{ 
                   if rad.lowercaseString.rangeOfString("  io ") != nil{ 
                        label.text = "\(label.text!)\(rad)" 
                        label.text! += "\r\r" 
                    } 
                } 
 
                if user_useract == 1{ 
                    if rad.lowercaseString.rangeOfString("  useract") != nil{ 
                        label.text = "\(label.text!)\(rad)" 
                        label.text! += "\r\r" 
                    } 
                } 
 
                if user_error == 1{ 
                    if rad.lowercaseString.rangeOfString("  error ") != nil{ 
                        label.text = "\(label.text!)\(rad)" 
                        label.text! += "\r\r" 
                    }  
                } 
               n=n+1 
            } 
        } 

请您参考如下方法:

您的应用没有响应,因为它在主线程上做了很多工作(尤其是您的非最佳字符串处理和大量属性访问可能是主要瓶颈)。你应该尝试offload that into a background thread .请注意,您需要在主线程上分配 UILabel 的 text 属性!因此,在变量中构建字符串,并在完成处理后将其分配给主线程上的 text 属性。

另外,很多自动释放的对象会被创建,直到您从 viewDidLoad 返回后的某个时间才会被释放。您应该添加一个每次迭代都清空的自动释放池,如下所示:

while n < lines { 
    autoreleasepool { 
        // Insert your "while" body here. 
    } 
} 

最后但同样重要的是,由于 while 中的最后一条语句是 n=n+1,因此您应该改用 for 循环:

for n in 0..<lines { 
    autoreleasepool { 
        // Insert your former "while" body here. 
    } 
} 

使用 NSMutableString 处理流程看起来像这样:

let priority = DISPATCH_QUEUE_PRIORITY_DEFAULT 
dispatch_async(dispatch_get_global_queue(priority, 0)) { 
    // Background thread. Do NOT access your label here! 
    let string = NSMutableString() 
    for n in 0..<lines { 
        autoreleasepool { 
            let rad: String = textArr[n] 
 
            if user_event == 1 { 
                if rad.lowercaseString.rangeOfString("  event ") != nil { 
                    string.appendString(rad) 
                    string.appendString("\r\r") 
                } 
            } 
 
            // ... 
        } 
    } 
 
    dispatch_async(dispatch_get_main_queue()) { 
        // Update label on main thread. 
        label.text = string 
    } 
}