代码之家  ›  专栏  ›  技术社区  ›  Jake2Finn

通过主机数组ping并在表中显示结果

  •  0
  • Jake2Finn  · 技术社区  · 6 年前

    我正在尝试ping包含不同主机的数组。在每个循环中,我都会根据ping是否成功保存一个图像(checkImg,errorImg)。之后,我想在一个表中显示信息(主机名和img)。

    线程1:致命错误:行中的索引超出范围:imgServer.image文件= UIImage(名称:statusImagesMain)[索引.row])

    所以我想不同主机的ping循环之前没有完成serverStatusTable.reloadData文件()已执行。

    你知道我能做些什么来克服这个问题吗?

    import UIKit
    
    class ServerVC: SimplePingDelegate, UITableViewDelegate, UITableViewDataSource {
    
        @IBOutlet weak var serverStatusTable: UITableView!
    
        let imageError = UIImage(named: "error")
        let imageCheck = UIImage(named: "check")
    
        var pings = ["www.apple.com", "www.appleidontknowwhy.de", "www.apple.com", "www.apple.com"]
    
        var hosts = [String]() // hostnames which get pinged
        var componentTextArray = [String]() // project names
        var statusImagesTemporary = [String]() // temporary store images
        var statusImagesMain = [String]() // array filled with temporary stored images
        var serverStatusMain = [String]() // server status string (connected, error)
        var serverStatusTemporary = [String]() // temporary server status
    
        override func viewDidLoad() {
            super.viewDidLoad()
    
            serverStatusTable.dataSource = self
            serverStatusTable.delegate = self
    
            statusImagesMain = ["error", "error", "error", "error"]
            componentTextArray = ["Project 1", "Project 2", "Project 3", "Project 4"]
            serverStatusMain = ["no data", "no data", "no data", "no data"]
            hosts = pings
    
            pingNext()
            serverStatusTable.reloadData()
            }
    
        override func viewDidAppear(_ animated: Bool) {
        // initial ping host process when loading the view
            startHostRequest()
        }
    
        @IBAction func refreshBtnAction(_ sender: Any) {
        // manual ping host process when clicking the button "refresh"
            startHostRequest()
        }
    
    
        func startHostRequest () {
            print("refresh server status")
            pingNext()
            // clear array before each host ping process in order for the array to keep only four items
            statusImagesMain.removeAll()
            serverStatusMain.removeAll()
    
            for statusImageTemporary in statusImagesTemporary {
                statusImagesMain.append(statusImageTemporary)
            }
            for i in serverStatusTemporary {
                serverStatusMain.append(i)
            }
            serverStatusTable.reloadData()
        }
    
        func pingNext() {
            guard pings.count > 0 else {
                return
            }
            let ping = pings.removeFirst()
            PlainPing.ping(ping, withTimeout: 1.0, completionBlock: { (timeElapsed:Double?, error:Error?) in
                if let latency = timeElapsed {
                    print("\(ping) latency (ms): \(latency)")
                    // fill temporary arrays with img and serverStatus text for successful connection
                    self.statusImagesTemporary.append("check")
                    self.serverStatusTemporary.append("Running ")
                }
                if let error = error {
                    print("error: \(error.localizedDescription)")
                    // fill temporary arrays with img and serverStatus text for failed connection attempt
                    self.statusImagesTemporary.append("error")
                    self.serverStatusTemporary.append("Error ")
                }
                self.pingNext()
            })
        }
    
    // fill table with host data
    
        func numberOfSections(in tableView: UITableView) -> Int {
            return 1
        }
    
        func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
            return componentTextArray.count
        }
    
        func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
            let cell = serverStatusTable.dequeueReusableCell(withIdentifier: "serverStatusCell", for: indexPath)
    
            let lblServerStatus : UILabel = cell.contentView.viewWithTag(8) as! UILabel
            let imgServer : UIImageView = cell.contentView.viewWithTag(7) as! UIImageView
    
    
            imgServer.image = UIImage(named: statusImagesMain[indexPath.row])
            lblServerStatus.text = serverStatusMain[indexPath.row]
    
            return cell
        }
    }
    
    1 回复  |  直到 6 年前
        1
  •  1
  •   Jon Roach    6 年前

    你的错误在于 startHostRequest() tableView(_ tableView: UITableView, numberOfRowsInSection section: Int)

    你收到了吗 statusImagesTemporary statusImagesMain ,和 statusImageTemporary .reloadData() . tableView(tableView:UITableView,numberOfRowsInSection:Int) 退货 componentTextArray.count 总是4。当这两个放在一起一次 startHostRequest() 称为重新加载表,指示有4行,但有0行数据要填充到行中。

    管理您的 UITableView 可以通过使用 ALTableViewHelper Framework Central here ]. 这个 s细胞是为你保存的-在你的情况下,与 状态图像临时 :

    class ServerVC: UIViewController, UITableViewDelegate {
    
        @IBOutlet weak var serverStatusTable: UITableView!
    
        @objc let imageError = UIImage(named: "error")
        @objc let imageCheck = UIImage(named: "check")
    
        var pings = ["www.apple.com", "www.appleidontknowwhy.de", "www.apple.com", "www.apple.com"]
    
        var hosts = [String]() // hostnames which get pinged
        @objc var componentTextArray = [String]() // project names
        @objc var serverStatusMain = NSMutableArray() // not [String]() to allow changes to be observed
    
        override func viewDidLoad() {
            super.viewDidLoad()
            // Do any additional setup after loading the view, typically from a nib.
    
            // do not set dataSource, but instead:
            serverStatusTable.setHelperString(
                "section\n" +
                " body\n" +
                "  serverStatusCell * serverStatusMain\n" +
                "   $.viewWithTag:(8).text <~ @[1] == 'error' ? 'Error ' : 'Running '\n" +
                "   $.viewWithTag:(7).image <~ @[1] == 'error' ? imageError : imageCheck \n" +
                "   $.viewWithTag:(2).text <~ componentTextArray[@[0]]\n" +
                "", context:self)
            // @ is the value from the array (serverStatusMain), and $ is the serverStatusCell for @
            // The selector for UIView.viewWithTag() is 'viewWithTag:', which is why you see that in the helper string
            // Short arrays were added below as the values in serverStatusMain. In each short array:
            //   [0] is the index into hosts[] and componentTextArray[]
            //   [1] is the result of the ping, ie "check" or "error"
            //   so @[0] is the index and @[1] is the result of the ping
    
            serverStatusTable.delegate = self
    
            componentTextArray = ["Project 1", "Project 2", "Project 3", "Project 4"]
            hosts = pings
        }
    
        override func didReceiveMemoryWarning() {
            super.didReceiveMemoryWarning()
            // Dispose of any resources that can be recreated.
        }
    
    
        override func viewDidAppear(_ animated: Bool) {
            // initial ping host process when loading the view
            startHostRequest()
        }
    
        @IBAction func refreshBtnAction(_ sender: Any) {
            // manual ping host process when clicking the button "refresh"
            startHostRequest()
        }
    
        func startHostRequest () {
            // I thought you might need this here so that the 2nd and later ‘starts’ do the whole list
            pings = hosts
    
            // This will empty your UITableView
            serverStatusMain.removeAllObjects()
    
            print("refresh server status")
            pingNext()
        }
    
        func pingNext() {
            guard pings.count > 0 else {
                return
            }
            let ping = pings.removeFirst()
            PlainPing.ping(ping, withTimeout: 1.0, completionBlock:  { [weak self](timeElapsed:Double?, error:Error?) in
                if let me = self {
                    if let latency = timeElapsed {
                        print("\(ping) latency (ms): \(latency)")
                        me.serverStatusMain.add([me.serverStatusMain.count, "check"])
                    }
                    if let error = error {
                        print("error: \(error.localizedDescription)")
                        me.serverStatusMain.add([me.serverStatusMain.count, "error"])
                    }
                    me.pingNext()
                }
            })
        }
    }
    

    您可以看到包含此代码的完整演示项目 here