简体   繁体   English

iOS swift tableview单元格用于解析查询数据

[英]iOS swift tableview cell for parse query data

override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as UITableViewCell
    var query = PFQuery(className:"category")
    let object = objects[indexPath.row] as String  

    query.whereKey("type", equalTo:"DRUM")
    query.findObjectsInBackgroundWithBlock {
        (objects: [AnyObject]!, error: NSError!) -> Void in
        if error == nil {
            for object in objects {
                NSLog("%@", object.objectId)
                let abc = object["link"]
                println("the web is \(abc)")

            cell.textLabel!.text = "\(abc)"
            }
        } else {
            NSLog("Error: %@ %@", error, error.userInfo!)
        }
    }
    return cell
}

截图 after add the let object = objects[indexPath.row] as String can't load the view, delete the line show only one row successfully. 在将let object = objects[indexPath.row] as String无法加载视图后,删除仅成功显示一行的行。

First I advise you to get your cell data outside cellForRowAtIndexPath. 首先,我建议您将单元格数据获取到cellForRowAtIndexPath之外。 This function is not a good place to receive data from parse. 此函数不是从解析接收数据的好地方。 Make another function and create a class variable and put handle getting data from there. 创建另一个函数并创建一个类变量,然后放置从那里获取数据的句柄。

let object = objects[indexPath.row] as String  
for object in objects 

Try not to use same variable names for different stuff, as they will confuse you. 尽量不要对不同的东西使用相同的变量名,因为它们会使您感到困惑。

This line is not contributing to anything at the moment it seems. 目前看来,这条线没有任何帮助。 Try deleting it: 尝试删除它:

let object = objects[indexPath.row] as String  

First lets have principles in mind. 首先让我们牢记原则。 Don't ever update UI from a separate thread, its behavior is unexpected or undefined. 永远不要从单独的线程更新UI,因为它的行为是意外的或未定义的。 It works or works weird. 它工作或工作很奇怪。

Second, the problem you have is the when the VC gets loaded the tableView's datasource is called there and then on the main thread. 其次,您遇到的问题是,当VC加载时,在其中调用tableView的数据源,然后在主线程上调用。 Now you tried to add something on the cell by doing a Async call in separate thread which will take time and main thread is not waiting when the call to parse is being done. 现在,您尝试通过在单独的线程中进行异步调用来在单元格上添加一些内容,这将花费一些时间,并且在完成解析调用时主线程不会等待。 If you have difficulty in Async please take a look at the documentation its really important to get a good grasp of the few terms and the principles. 如果您在使用Async时遇到困难,请查看文档,它对于掌握一些术语和原理非常重要。

The thing is your main thread runs top to bottom without waiting each call to server thats async in the cell generation. 关键是您的主线程从上到下运行,而不必等待每次在单元生成中对异步服务器的调用。 So the result of that call will post later on and you are not posting on main thread too. 因此,该调用的结果将稍后发布,并且您也不会在主线程上发布。

Moreover, i would suggest you don't do this approach for big projects or manageable code base. 而且,我建议您不要对大型项目或可管理的代码库采用这种方法。 I generally do is: 我通常做的是:

  1. when the view loads call the Parse with the needed information 当视图加载时,使用所需的信息调用Parse
  2. Wait for that on a computed variable which i will observe to reload table views once I'm conformed i have the data. 等待一个计算出的变量,一旦我确定了数据,我将观察该变量重新加载表视图。
  3. Initially table view will have 0 rows and thats fine. 最初,表视图将具有0行,这很好。 Ill make a spinner dance during that time. 在那段时间里,生病了一场飞舞。

I hope i made some issues clear. 我希望我能阐明一些问题。 Hope it helps you. 希望对您有帮助。 Cheers! 干杯!

 //a computed var that is initialized to empty array of string or anything you like
//we are observing the value of datas. Observer Pattern.
var datas = [String](){
    didSet{
        dispatch_async(dispatch_get_main_queue(), {
            //we might be called from the parse block which executes in seperate thread
            tableView.reloadData()
        })
    }
}

func viewDidLoad(){
    super.viewDidLoad()
    //call the parse to fetch the data and store in the above variable 
    //when this succeeds then the table will be reloaded automatically
    getDataFromParse()
}


//get the data: make it specific to your needs
func getDataFromParse(){
    var query = PFQuery(className:"category")
    //let object = objects[indexPath.row] as String         //where do you use this in this block
    var tempHolder = [String]()

    query.whereKey("type", equalTo:"DRUM")
    query.findObjectsInBackgroundWithBlock {
        (objects: [AnyObject]?, error: NSError?) -> Void in
        if error == nil && objects != nil {
            for object in objects!{
                //dont forget to cast it to PFObject
                let abc = (object as! PFObject).objectForKey("link") as? String ?? ""   //or as! String
                println("the web is \(abc)")
                tempHolder.append(abc)
            }
        } else {
            print("error")  //do some checks here
        }
    }
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as! UITableViewCell
    cell.textLabel!.text = datas[indexPath.row]
    return cell
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM