0

编辑 1:在帖子底部添加了我的修订 cellForRowAtIndexPath 代码

编辑 2:添加了我的新编辑元素代码

我很难正确解开我的 UILabel 文本输入,所以我的所有文本都说“可选(作者姓名)”(例如,这是一个报纸的应用程序)。我试图以不同的方式强制解开我的变量,但无法使其工作。

我的 UILabel 的文本输入是通过以下方式创建的。对应的类是“EditorialElement”,它具有以下属性定义:

class EditorialElement: NSObject {

var title: String!           // title
var nodeID: Int?             // nid
var timeStamp: Int       // revision_timestamp
var imageURL: String?       // image_url
var author: String?          // author

var issueNumber: String!     // issue_int
var volumeNumber: String!    // volume_int

var articleContent: String! // html_content

/* To get an NSDate objec from Unix timestamp
var date = NSDate(timeIntervalSince1970: timeStamp) */

init(title: String, nodeID: Int, timeStamp: Int, imageURL: String, author: String, issueNumber: String, volumeNumber: String, articleContent: String) {
    self.title = title
    self.nodeID = nodeID
    self.timeStamp = timeStamp
    self.imageURL = imageURL
    self.author = author
    self.issueNumber = issueNumber
    self.volumeNumber = volumeNumber
    self.articleContent = articleContent
}

override func isEqual(object: AnyObject!) -> Bool {
    return (object as! EditorialElement).nodeID == self.nodeID
}

override var hash: Int {
    return (self as EditorialElement).nodeID!
}

}

然后,我使用这个类从我的 JSON 文件中检索数据,并将其解析为“edititorialObjects”数组(对不起所有的评论和错误的间距):

func populateEditorials() {
    if populatingEditorials {
        return
    }
    populatingEditorials = true

    Alamofire.request(GWNetworking.Router.Editorials(self.currentPage)).responseJSON() { response in
        if let JSON = response.result.value {
           /*
        if response.result.error == nil {
            */

            /* Creating objects for every single editorial is long running work, so we put that work on a background queue, to keep the app very responsive. */
            dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0)) {


                /* Making an array of all the node IDs from the JSON file */
                var nodeIDArray : [Int]


                if (JSON .isKindOfClass(NSDictionary)) {

                    for node in JSON as! Dictionary<String, AnyObject> {

                    let nodeIDValue = node.0
                    var lastItem : Int = 0

                    self.nodeIDArray.addObject(nodeIDValue)

                    if let editorialElement : EditorialElement = EditorialElement(title: "init", nodeID: 0, timeStamp: 0, imageURL: "init", author: "init", issueNumber: "init", volumeNumber: "init", articleContent: "init") {

                editorialElement.title = node.1["title"] as! String
                editorialElement.nodeID = Int(nodeIDValue)

                let timeStampString = node.1["revision_timestamp"] as! String
                editorialElement.timeStamp = Int(timeStampString)!

                editorialElement.imageURL = String(node.1["image_url"])
                editorialElement.author = String(node.1["author"])
                editorialElement.issueNumber = String(node.1["issue_int"])
                editorialElement.volumeNumber = String(node.1["volume_int"])
                editorialElement.articleContent = String(node.1["html_content"])

                lastItem = self.editorialObjects.count

                print (editorialElement.nodeID)


                self.editorialObjects.addObject(editorialElement)


                /* Sorting the elements in order of newest to oldest (as the array index increases] */
                let timestampSortDescriptor = NSSortDescriptor(key: "timeStamp", ascending: false)
                self.editorialObjects.sortUsingDescriptors([timestampSortDescriptor])

                let indexPaths = (lastItem..<self.editorialObjects.count).map { NSIndexPath(forItem: $0, inSection: 0) }


               /*

                        nodeIDArray[nodeCounter] = jsonValue{nodeCounter}.string
                        let editorialInfos : EditorialElement = ((jsonValue as! NSDictionary].1["\(nodeIDArray[nodeCounter]]"] as! [NSDictionary]].map { EditorialElement(title: $0["title"] as! String, nodeID: $0["nid"] as! Int, timeStamp: $0["revision_timestamp"] as! Int, imageURL: $0["image_url"] as! String, author: $0["author"], issueNumber: $0["issue_int"] as! Int, volumeNumber: $0["volume_int"] as! Int, articleContent: $0["html_content"] as! String] // I am going to try to break this line down to simplify it and fix the build errors
*/


}

                print(self.editorialObjects.count)

            }
        }

                dispatch_async(dispatch_get_main_queue()) {
                    self.editorialsTableView.reloadData()
                }

                self.currentPage++
        }
    }

        self.populatingEditorials = false
}
}

然后我只是在我的 cellForRowAtIndexPath 方法中使用这些对象作为我的标签:

override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {

    let row = indexPath.row

    let cell = tableView.dequeueReusableCellWithIdentifier(EditorialTableCellIdentifier, forIndexPath: indexPath) as! EditorialsTableViewCell

    let title = (editorialObjects.objectAtIndex(indexPath.row) as! EditorialElement).title

    let timeStamp = (editorialObjects.objectAtIndex(indexPath.row) as! EditorialElement).timeStamp
    let timeStampDateObject = NSDate(timeIntervalSince1970: NSTimeInterval(Int((editorialObjects.objectAtIndex(indexPath.row) as! EditorialElement).timeStamp)))
    timeStampDateString = dateFormatter.stringFromDate(timeStampDateObject)

    let imageURL = (editorialObjects.objectAtIndex(indexPath.row) as! EditorialElement).imageURL

    let author : String! = (editorialObjects.objectAtIndex(indexPath.row) as! EditorialElement).author!

    let issueNumber = (editorialObjects.objectAtIndex(indexPath.row) as! EditorialElement).issueNumber
    let volumeNumber = (editorialObjects.objectAtIndex(indexPath.row) as! EditorialElement).volumeNumber

    let articleContent = (editorialObjects.objectAtIndex(indexPath.row) as! EditorialElement).articleContent

    let nodeID = (editorialObjects.objectAtIndex(indexPath.row) as! EditorialElement).nodeID

    /* Unlike the Pictures Collection View, there is no need to create another Alamofire request here, since we already have all the content we want from the JSON we downloaded. There is no URL that we wish to place a request to to get extra content. */

    cell.editorialHeadlineLabel.font = UIFont.preferredFontForTextStyle(UIFontTextStyleHeadline)
    cell.editorialHeadlineLabel.text = title

    cell.editorialAuthorLabel.font = UIFont.preferredFontForTextStyle(UIFontTextStyleSubheadline)
    cell.editorialAuthorLabel.text = author

    cell.editorialPublishDateLabel.font = UIFont.preferredFontForTextStyle(UIFontTextStyleSubheadline)
    cell.editorialPublishDateLabel.text = timeStampDateString

    return cell
}

我应该在哪里强制解开我的变量?

编辑 1:修改后的代码

override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {

    let row = indexPath.row

    guard let cell = tableView.dequeueReusableCellWithIdentifier(EditorialTableCellIdentifier, forIndexPath: indexPath) as? EditorialsTableViewCell else {
        print ("error: editorialsTableView cell is not of class EditorialsTableViewCell, we will use RandomTableViewCell instead")
        return tableView.dequeueReusableCellWithIdentifier(EditorialTableCellIdentifier, forIndexPath: indexPath) as! RandomTableViewCell
    }

    if let editorialObject = editorialObjects.objectAtIndex(indexPath.row) as? EditorialElement {
        // we just unwrapped editorialObject

        let title = editorialObject.title ?? "" // if editorialObject.title == nil, then we return an empty string.

        let timeStampDateObject = NSDate(timeIntervalSince1970: NSTimeInterval(editorialObject.timeStamp))
        let timeStampDateString = dateFormatter.stringFromDate(timeStampDateObject)

        let author = editorialObject.author ?? ""

        let issueNumber = editorialObject.issueNumber ?? ""
        let volumeNumber = editorialObject.volumeNumber ?? ""

        let articleContent = editorialObject.articleContent ?? ""

        let nodeID = editorialObject.nodeID ?? 0


        cell.editorialHeadlineLabel.font = UIFont.preferredFontForTextStyle(UIFontTextStyleHeadline)
        cell.editorialHeadlineLabel.text = title

        cell.editorialAuthorLabel.font = UIFont.preferredFontForTextStyle(UIFontTextStyleSubheadline)
        cell.editorialAuthorLabel.text = String(author)

        cell.editorialPublishDateLabel.font = UIFont.preferredFontForTextStyle(UIFontTextStyleSubheadline)
        cell.editorialPublishDateLabel.text = timeStampDateString

    } else {

    }

    return cell
}

编辑 2:新的编辑元素代码

class EditorialElement: NSObject {

var title: String           // title
var nodeID: Int             // nid
var timeStamp: Int       // revision_timestamp
var imageURL: String       // image_url
var author: String       // author

var issueNumber: String     // issue_int
var volumeNumber: String    // volume_int

var articleContent: String // html_content

/* To get an NSDate objec from Unix timestamp
var date = NSDate(timeIntervalSince1970: timeStamp) */

init(title: String, nodeID: Int, timeStamp: Int, imageURL: String, author: String, issueNumber: String, volumeNumber: String, articleContent: String) {
    self.title = title
    self.nodeID = nodeID
    self.timeStamp = timeStamp
    self.imageURL = imageURL
    self.author = author
    self.issueNumber = issueNumber
    self.volumeNumber = volumeNumber
    self.articleContent = articleContent
}

override func isEqual(object: AnyObject!) -> Bool {
    return (object as! EditorialElement).nodeID == self.nodeID
}

override var hash: Int {
    return (self as EditorialElement).nodeID
}

}
4

3 回答 3

0

在大多数情况下,强制展开是一种代码异味除非您正在链接 IBOutlets 或在其他一些特殊情况下,否则不要使用它。尝试正确解开你的变量。

override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    let row = indexPath.row

    guard let cell = tableView.dequeueReusableCellWithIdentifier(EditorialTableCellIdentifier, forIndexPath: indexPath) as? EditorialsTableViewCell else {
      // if we fall here cell isn't a EditorialsTableViewCell
      // handle that properly
    }

    if let editorialObject = editorialObjects.objectAtIndex(indexPath.row) as? EditorialElement {
        // editorialObject here is unwrapped
        let title = editorialObject.title ?? "" // if editorialObject.title == nil we store empty string
        let timeStampDateObject = NSDate(timeIntervalSince1970: NSTimeInterval(editorialObject.timeStamp))
        let timeStampDateString = dateFormatter.stringFromDate(timeStampDateObject)

        cell.editorialHeadlineLabel.font = UIFont.preferredFontForTextStyle(UIFontTextStyleHeadline)
        cell.editorialHeadlineLabel.text = title

        cell.editorialPublishDateLabel.font = UIFont.preferredFontForTextStyle(UIFontTextStyleSubheadline)
        cell.editorialPublishDateLabel.text = timeStampDateString    
    } else {
      // no such editorial object - log error. 
      // return empty cell or do more sofisticated error handling

    }

    return cell
}
于 2015-10-14T15:46:30.220 回答
0

我的意见,将您的变量声明更改为not nil变量,例如:var author: String!

然后,当您为变量设置值时,empty character如果它为 nil,则将其设置为(或默认值):

editorialElement.author = String(node.1["author"]) ?? ""

之后,您可以使用您的变量而无需在任何地方展开。

于 2015-10-14T15:39:14.763 回答
0

夫妇的事情。1. 如果你知道那里会有东西,你应该只强行打开它们。但是,如果您对此非常有信心(或者您不希望/不希望应用程序在没有它们的情况下运行),那么您应该从一开始就强制拆开它们。只在代码中到处var imageURL: String?写是没有意义的。imageURL!optionals的重点是允许您优雅地处理对象可能为 nil 的情况。

无论如何,假设这对你来说是正确的结构,我要做的第一件事就是if let在索引处返回对象。所以写:

if let element = editorialObjects.objectAtIndex(indexPath.row) as? EditorialElement

现在您可以将其用作行elementEditorialElement整个单元格。从那里您可以决定如何/何时打开其他所有内容。

所以let author : String! = (editorialObjects.objectAtIndex(indexPath.row) as! EditorialElement).author!会变成

let author = element.author!或者您if let可以避免崩溃并处理它为零的情况。if let author = element.author { // do something }

于 2015-10-14T15:32:59.553 回答