Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/image-processing/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Arrays Swift 3 JSON到对象数组的速度非常慢_Arrays_Json_Object_Swift3_Swifty Json - Fatal编程技术网

Arrays Swift 3 JSON到对象数组的速度非常慢

Arrays Swift 3 JSON到对象数组的速度非常慢,arrays,json,object,swift3,swifty-json,Arrays,Json,Object,Swift3,Swifty Json,我正在将我的应用程序从swift 2升级到swift 3,在构建自定义对象数组时,性能会显著下降。在swift 2中,这需要几秒钟,而在swift 3中,这需要大约30秒。我使用alamofire返回swiftyJSON,返回大约3000行数据。alamofire返回速度很快,它通过这个json循环来构建定制对象数组的速度很慢。这些对象极大地简化了在构建表单元和将数据传递给新视图时编写的代码 代码: } }使用nil合并运算符将使您受益匪浅:self.ID=ID??“”您确定为ID、地址等指定一

我正在将我的应用程序从swift 2升级到swift 3,在构建自定义对象数组时,性能会显著下降。在swift 2中,这需要几秒钟,而在swift 3中,这需要大约30秒。我使用alamofire返回swiftyJSON,返回大约3000行数据。alamofire返回速度很快,它通过这个json循环来构建定制对象数组的速度很慢。这些对象极大地简化了在构建表单元和将数据传递给新视图时编写的代码

代码:

}


}

使用
nil合并运算符将使您受益匪浅:
self.ID=ID??“”
您确定为ID、地址等指定一个空字符串有意义吗?我不确定这是否最好,因为如果我尝试访问,它可以防止应用程序崩溃。我仍在努力解决可选项和展开变量的问题。这也不会导致崩溃<代码>self.ID=ID??“
if\u id!=nil{self.ID=_ID}else{self.ID=“”}
在您解决性能问题之前,我认为您将真正受益于了解更多有关optionals的信息。它们是语言不可或缺的一部分。首先,为什么所有这些变量都隐式地展开了选项(
String!
)?
class Customer {
var ID: String!
var sysName: String!
var address: String!
var contactID: String!

required init(_name:String?, _id: String?, _address:String?, _contactID:String?) {
    //print(json)
    if _id != nil {
        self.ID = _id
    }else{
        self.ID = ""
    }
    if _name != nil {
        self.sysName = _name
    }else{
        self.sysName = ""
    }

    if _address != nil {
        self.address = _address
    }else{
        self.address = "No Address on File"
    }
    if _contactID != nil {
        self.contactID = _contactID
    }else{
        self.contactID = ""
    }
}
Alamofire.request(API.Router.customerList()).responseJSON() {
        response in
        print(response.request ?? "")  // original URL request
        print(response.response ?? "") // URL response
        print(response.data ?? "")     // server data
        print(response.result)   // result of response serialization

        if let json = response.result.value {
            print("JSON: \(json)")
            self.customers = JSON(json)
            self.parseJSON()

        }
    }

func parseJSON(){
    let jsonCount = self.customers["customers"].count
    self.totalCustomers = jsonCount
        for i in 0 ..< jsonCount {
            self.loadedCustomers = i
            print("customer = \(self.customers["customers"][i]    ["sysName"].string!)")
            //VERY SLOW
            //create a customer object
            let customer = Customer( _name: self.customers["customers"][i]["sysName"].string!, _id: self.customers["customers"][i]["ID"].string!, _address: self.customers["customers"][i]["mainAddr"].string!, _contactID: self.customers["customers"][i]["contactID"].string!)
            //add customer to customer array
            self.customersArray.append(customer)
        }
        self.layoutViews()  //build view, call all table methods
    }
var indicator: SDevIndicator!
var totalCustomers:Int!
//data arrays
var ids = [String]()
var names = [String]()
var addresses = [String]()
var searchController:UISearchController!
var currentSearchMode = SearchMode.name
var customerTableView:TableView = TableView()
var layoutVars:LayoutVars = LayoutVars()
var sections : [(index: Int, length :Int, title: String)] = Array()
var customersSearchResults:[String] = []
var shouldShowSearchResults:Bool = false
let viewsConstraint_V:NSArray = []
let viewsConstraint_V2:NSArray = []

override func viewDidLoad() {
    super.viewDidLoad()
    title = "Customer List"
    view.backgroundColor = layoutVars.backgroundColor
    getCustomerList()
}


func getCustomerList() {
    //remove any added views (needed for table refresh
    for view in self.view.subviews{
        view.removeFromSuperview()
    }

    // Show Indicator
    indicator = SDevIndicator.generate(self.view)!


    Alamofire.request(API.Router.customerList()).responseJSON() {
        response in
        //print(response.request ?? "")  // original URL request
        //print(response.response ?? "") // URL response
        //print(response.data ?? "")     // server data
        //print(response.result)   // result of response serialization
        do {
            if let data = response.data,
                let json = try JSONSerialization.jsonObject(with: data) as? [String: Any],
                let customers = json["customers"] as? [[String: Any]] {
                for customer in customers {
                    if let id = customer["ID"] as? String {
                        self.ids.append(id)
                    }
                    if let name = customer["sysName"] as? String {
                        self.names.append(name)
                    }

                    if let address = customer["mainAddr"] as? String {
                        self.addresses.append(address)
                    }
                }
            }
        } catch {
            print("Error deserializing JSON: \(error)")
        }
        // build sections based on first letter(json is already sorted alphabetically)
        var index = 0;
        var firstCharacterArray:[String] = [" "]
        for i in 0 ..< self.names.count {
            let stringToTest = self.names[i].uppercased()
            let firstCharacter = String(stringToTest[stringToTest.startIndex])

            if(i == 0){
                firstCharacterArray.append(firstCharacter)
            }
            if !firstCharacterArray.contains(firstCharacter) {
                let title = firstCharacterArray[firstCharacterArray.count - 1]
                firstCharacterArray.append(firstCharacter)
                let newSection = (index: index, length: i - index, title: title)
                self.sections.append(newSection)
                index = i;
            }
            if(i == self.names.count - 1){
                let title = firstCharacterArray[firstCharacterArray.count - 1]
                let newSection = (index: index, length: i - index, title: title)
                self.sections.append(newSection)
            }
        }
        self.layoutViews()
    }
}


func layoutViews(){
    indicator.dismissIndicator()
    searchController = UISearchController(searchResultsController: nil)
    searchController.searchBar.placeholder = "Search Customers"
    searchController.searchResultsUpdater = self
    searchController.delegate = self
    searchController.searchBar.delegate = self
    searchController.dimsBackgroundDuringPresentation = false
    searchController.hidesNavigationBarDuringPresentation = false
    navigationItem.titleView = searchController.searchBar

    let items = ["Name","Address"]
    let customSC = SegmentedControl(items: items)
    customSC.selectedSegmentIndex = 0

    customSC.addTarget(self, action: #selector(self.changeSearchOptions(sender:)), for: .valueChanged)
    self.view.addSubview(customSC)

    self.customerTableView.delegate  =  self
    self.customerTableView.dataSource = self
    self.customerTableView.register(CustomerTableViewCell.self, forCellReuseIdentifier: "cell")
    self.view.addSubview(self.customerTableView)
    //auto layout group
    let viewsDictionary = [
        "view2":customSC,
        "view3":self.customerTableView
    ]as [String:AnyObject]
    let sizeVals = ["fullWidth": layoutVars.fullWidth,"width": layoutVars.fullWidth - 30,"navBottom":layoutVars.navAndStatusBarHeight,"height": self.view.frame.size.height - 100] as [String:Any]
    self.view.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|[view2(fullWidth)]", options: [], metrics: sizeVals, views: viewsDictionary))
    self.view.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|[view3(fullWidth)]", options: [], metrics: sizeVals, views: viewsDictionary))
    self.view.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:|-navBottom-[view2(40)][view3(height)]", options: [], metrics: sizeVals, views: viewsDictionary))
}
func changeSearchOptions(sender: UISegmentedControl) {
    switch sender.selectedSegmentIndex {
    case 0:
        currentSearchMode = .name
        break
    case 1:
        currentSearchMode = .address
        break
    default:
        currentSearchMode = .name
        break
    }
    filterSearchResults()
}


func updateSearchResults(for searchController: UISearchController) {
    filterSearchResults()
}

func filterSearchResults(){
    customersSearchResults = []
    switch  currentSearchMode {
    case .name:
        self.customersSearchResults = self.names.filter({( aCustomer: String ) -> Bool in
            return (aCustomer.lowercased().range(of: self.searchController.searchBar.text!.lowercased()) != nil)            })
        break
    case .address:
        self.customersSearchResults = self.addresses.filter({( aCustomer: String) -> Bool in
            return (aCustomer.lowercased().range(of: self.searchController.searchBar.text!.lowercased()) != nil)
        })
        break
    }
    self.customerTableView.reloadData()
}

func searchBarTextDidBeginEditing(_ searchBar: UISearchBar) {
    //print("searchBarTextDidBeginEditing")
    shouldShowSearchResults = true
    self.customerTableView.reloadData()
}

func searchBarCancelButtonClicked(_ searchBar: UISearchBar) {
    shouldShowSearchResults = false
    self.customerTableView.reloadData()
}

func searchBarSearchButtonClicked(_ searchBar: UISearchBar) {
    if !shouldShowSearchResults {
        shouldShowSearchResults = true
        self.customerTableView.reloadData()
    }
    searchController.searchBar.resignFirstResponder()
}

/////////////// TableView Delegate Methods   ///////////////////////
func numberOfSections(in tableView: UITableView) -> Int {
    if shouldShowSearchResults{
        return 1
    }else{
        return sections.count
    }
}


func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
     //print("titleForHeaderInSection")
    if shouldShowSearchResults{
        return nil
    }else{
        if(sections[section].title == "#"){
            return "    # \(self.totalCustomers)  Customers Found"
        }else{
            return "    " + sections[section].title //hack way of indenting section text

        }
    }

}
func sectionIndexTitles(for tableView: UITableView) -> [String]?{
    print("sectionIndexTitlesForTableView 1")
    if shouldShowSearchResults{
        return nil
    }else{
        //print("sectionIndexTitlesForTableView \(sections.map { $0.title })")
        return sections.map { $0.title }

    }
}





func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
    //print("heightForHeaderInSection")
    if shouldShowSearchResults{
        return 0
    }else{
        return 50
    }
}

func tableView(_ tableView: UITableView, sectionForSectionIndexTitle title: String, at index: Int) -> Int {
    return index
}





func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    //print("numberOfRowsInSection")
    if shouldShowSearchResults{
        return self.customersSearchResults.count
    } else {
        return sections[section].length
    }
}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

    let cell = customerTableView.dequeueReusableCell(withIdentifier: "cell") as! CustomerTableViewCell
    customerTableView.rowHeight = 50.0
    if shouldShowSearchResults{
        let searchString = self.searchController.searchBar.text!.lowercased()
        if(currentSearchMode == .name){
            cell.nameLbl.text = self.customersSearchResults[indexPath.row]
            cell.name = self.customersSearchResults[indexPath.row]
            if let i = self.names.index(of: cell.nameLbl.text!) {
                //print("\(cell.nameLbl.text!) is at index \(i)")
                cell.addressLbl.text = self.addresses[i]
                cell.address = self.addresses[i]
                cell.id = self.ids[i]
            } else {
                cell.addressLbl.text = ""
                cell.address = ""
                cell.id = ""
            }
            //text highlighting
            let baseString:NSString = cell.name as NSString
            let highlightedText = NSMutableAttributedString(string: cell.name)
            var error: NSError?
            let regex: NSRegularExpression?
            do {
                regex = try NSRegularExpression(pattern: searchString, options: .caseInsensitive)
            } catch let error1 as NSError {
                error = error1
                regex = nil
            }
            if let regexError = error {
                print("Oh no! \(regexError)")
            } else {
                for match in (regex?.matches(in: baseString as String, options: NSRegularExpression.MatchingOptions(), range: NSRange(location: 0, length: baseString.length)))! as [NSTextCheckingResult] {
                    highlightedText.addAttribute(NSBackgroundColorAttributeName, value: UIColor.yellow, range: match.range)
                }
            }
            cell.nameLbl.attributedText = highlightedText

        }else{//address search mode
            cell.addressLbl.text = self.customersSearchResults[indexPath.row]
            cell.address = self.customersSearchResults[indexPath.row]

            if let i = self.addresses.index(of: cell.addressLbl.text!) {
                cell.nameLbl.text = self.names[i]
                cell.name = self.names[i]
                cell.id = self.ids[i]
            } else {
                cell.nameLbl.text = ""
                cell.name = ""
                cell.id = ""
            }
            //text highlighting
            let baseString:NSString = cell.address as NSString
            let highlightedText = NSMutableAttributedString(string: cell.address)
            var error: NSError?
            let regex: NSRegularExpression?
            do {
                regex = try NSRegularExpression(pattern: searchString, options: .caseInsensitive)
            } catch let error1 as NSError {
                error = error1
                regex = nil
            }
            if let regexError = error {
                print("Oh no! \(regexError)")
            } else {
                for match in (regex?.matches(in: baseString as String, options: NSRegularExpression.MatchingOptions(), range: NSRange(location: 0, length: baseString.length)))! as [NSTextCheckingResult] {
                    highlightedText.addAttribute(NSBackgroundColorAttributeName, value: UIColor.yellow, range: match.range)
                }

            }
            cell.addressLbl.attributedText = highlightedText
        }
    } else {
        //print("make cell")
        cell.id = self.ids[sections[indexPath.section].index + indexPath.row]
        cell.name = self.names[sections[indexPath.section].index + indexPath.row]
        cell.address = self.addresses[sections[indexPath.section].index + indexPath.row]

        cell.nameLbl.text = self.names[sections[indexPath.section].index + indexPath.row]
        cell.addressLbl.text = self.addresses[sections[indexPath.section].index + indexPath.row]
    }
    return cell
}

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {

    let indexPath = tableView.indexPathForSelectedRow;
    let currentCell = tableView.cellForRow(at: indexPath!) as! CustomerTableViewCell
    let customerViewController = CustomerViewController(_customerID: currentCell.id)
    navigationController?.pushViewController(customerViewController, animated: false )

    tableView.deselectRow(at: indexPath!, animated: true)
}
override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}