编辑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文件中检索数据并将其解析为“editorialObjects”数组(抱歉所有注释和错误的间距):
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
}
}
答案 0 :(得分:0)
夫妻俩。 1.如果你知道那里会有什么东西,你应该强行打开它们。但是如果你对此非常有信心(或者你不希望/希望应用程序在没有它们的情况下工作)那么你应该让它们从开始就被强行打开。只需在代码中的任何地方写var imageURL: String?
,imageURL!
就没有意义了。选项的 point 允许您优雅地处理对象可能为零的情况。
无论如何,假设这是你正确的结构,我要做的第一件事是if let
在索引处返回对象。所以写道:
if let element = editorialObjects.objectAtIndex(indexPath.row) as? EditorialElement
现在,您可以在行的整个单元格中使用element
作为EditorialElement
。从那里你可以决定如何/何时打开其他一切。
所以let author : String! = (editorialObjects.objectAtIndex(indexPath.row) as! EditorialElement).author!
将成为
let author = element.author!
或者您可以if let
以避免崩溃并处理它为零的情况。 if let author = element.author { // do something }
答案 1 :(得分:0)
我的意见是,将变量声明更改为not nil
变量,例如:var author: String!
然后,当您为变量设置值时,如果它是零,则将其设置为empty character
(或默认值):
editorialElement.author = String(node.1["author"]) ?? ""
之后,您可以使用您的变量而无需在任何地方展开。
答案 2 :(得分:0)
在大多数情况下,强制解包是code smell。除非您要关联IBOutlets或some other exceptional cases,否则不要使用它。尝试正确解开变量。
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
}