我正在尝试同时学习 Swift 和 iOS 开发的基础知识,所以请多多包涵。我有一个TableViewController,它首先解析一个本地JSON 文件并将它的非常简单的数据渲染到TableViewCell 和SectionHeaderViews。在同一个 TableViewController 中,我正在调用一个返回数据的 JSON 端点,然后我将其设置为变量,以便我可以访问我真正想要的达到(API 结构不太理想)。所以,我最终将正确的数据设置为 self.tableData 然后调用 self.tableView.reloadData() 但没有任何反应。什么给了?
import UIKit
class BusinessTableViewController: UITableViewController {
var data: NSMutableData = NSMutableData()
var tableData: NSArray = NSArray()
@lazy var Business: NSArray = {
let pathTCT = NSBundle.mainBundle().pathForResource("TCT", ofType: "json")
let data = NSData.dataWithContentsOfFile(pathTCT, options: nil, error: nil)
return NSJSONSerialization.JSONObjectWithData(data, options: nil, error: nil) as NSArray
}()
override func viewDidLoad() {
super.viewDidLoad()
navigationItem.titleView = UIImageView(image: UIImage(named: "growler"))
tableView.registerClass(BeerTableViewCell.self, forCellReuseIdentifier: "cell")
tableView.separatorStyle = .None
fetchKimono()
}
override func numberOfSectionsInTableView(tableView: UITableView!) -> Int {
// return Business.count
return 1
}
override func tableView(tableView: UITableView?, numberOfRowsInSection section: Int) -> Int {
let biz = Business[section] as NSDictionary
let results = biz["results"] as NSDictionary
let beers = results["collection1"] as NSArray
return beers.count
}
override func tableView(tableView: UITableView?, cellForRowAtIndexPath indexPath: NSIndexPath?) -> UITableViewCell? {
let cell = tableView!.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath!) as BeerTableViewCell
if let path = indexPath {
let biz = Business[path.section] as NSDictionary
let results = biz["results"] as NSDictionary
let beers = results["collection1"] as NSArray
let beer = beers[path.row] as NSDictionary
cell.titleLabel.text = beer["BeerName"] as String
}
return cell
}
override func tableView(tableView: UITableView!, titleForHeaderInSection section: Int) -> String! {
let biz = Business[section] as NSDictionary
return biz["name"] as String
}
override func tableView(tableView: UITableView!, viewForHeaderInSection section: Int) -> UIView! {
let biz = Business[section] as NSDictionary
let view = LocationHeaderView()
view.titleLabel.text = (biz["name"] as String).uppercaseString
return view
}
override func tableView(tableView: UITableView!, heightForHeaderInSection section: Int) -> CGFloat {
return 45
}
func fetchKimono() {
var urlPath = "names have been changed to protect the innocent"
var url: NSURL = NSURL(string: urlPath)
var request: NSURLRequest = NSURLRequest(URL: url)
var connection: NSURLConnection = NSURLConnection(request: request, delegate: self, startImmediately: false)
connection.start()
}
func connection(didReceiveResponse: NSURLConnection!, didReceiveResponse response: NSURLResponse!) {
// Recieved a new request, clear out the data object
self.data = NSMutableData()
}
func connection(connection: NSURLConnection!, didReceiveData data: NSData!) {
// Append the recieved chunk of data to our data object
self.data.appendData(data)
}
func connectionDidFinishLoading(connection: NSURLConnection!) {
// Request complete, self.data should now hold the resulting info
// Convert the retrieved data in to an object through JSON deserialization
var err: NSError
var jsonResult: NSDictionary = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers, error: nil) as NSDictionary
var results: NSDictionary = jsonResult["results"] as NSDictionary
var collection: NSArray = results["collection1"] as NSArray
if jsonResult.count>0 && collection.count>0 {
var results: NSArray = collection as NSArray
self.tableData = results
self.tableView.reloadData()
}
}
}
最佳答案
您需要通过以下方式在 UI 线程上重新加载表格:
//swift 2.3
dispatch_async(dispatch_get_main_queue(), { () -> Void in
self.tableView.reloadData()
})
//swift 5
DispatchQueue.main.async{
self.tableView.reloadData()
}
跟进:
connection.start() 方法的一个更简单的替代方法是使用 NSURLConnection.sendAsynchronousRequest(...)
//NSOperationQueue.mainQueue() is the main thread
NSURLConnection.sendAsynchronousRequest(NSURLRequest(URL: url), queue: NSOperationQueue.mainQueue()) { (response, data, error) -> Void in
//check error
var jsonError: NSError?
let json: AnyObject? = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.allZeros, error: &jsonError)
//check jsonError
self.collectionView?.reloadData()
}
这不允许您灵活地跟踪字节,例如您可能希望通过 bytesDownloaded/bytesNeeded 计算下载进度
关于ios - self.tableView.reloadData() 在 Swift 中不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24112844/
如果您尝试在Ruby中的nil对象上调用方法,则会出现NoMethodError异常并显示消息:"undefinedmethod‘...’fornil:NilClass"然而,有一个tryRails中的方法,如果它被发送到一个nil对象,它只返回nil:require'rubygems'require'active_support/all'nil.try(:nonexisting_method)#noNoMethodErrorexceptionanymore那么try如何在内部工作以防止该异常? 最佳答案 像Ruby中的所有其他对象
在Rails4.0.2中,我使用s3_direct_upload和aws-sdkgems直接为s3存储桶上传文件。在开发环境中它工作正常,但在生产环境中它会抛出如下错误,ActionView::Template::Error(noimplicitconversionofnilintoString)在View中,create_cv_url,:id=>"s3_uploader",:key=>"cv_uploads/{unique_id}/${filename}",:key_starts_with=>"cv_uploads/",:callback_param=>"cv[direct_uplo
这里有一个很好的答案解释了如何在Ruby中下载文件而不将其加载到内存中:https://stackoverflow.com/a/29743394/4852737require'open-uri'download=open('http://example.com/image.png')IO.copy_stream(download,'~/image.png')我如何验证下载文件的IO.copy_stream调用是否真的成功——这意味着下载的文件与我打算下载的文件完全相同,而不是下载一半的损坏文件?documentation说IO.copy_stream返回它复制的字节数,但是当我还没有下
我正在尝试解析一个文本文件,该文件每行包含可变数量的单词和数字,如下所示:foo4.500bar3.001.33foobar如何读取由空格而不是换行符分隔的文件?有什么方法可以设置File("file.txt").foreach方法以使用空格而不是换行符作为分隔符? 最佳答案 接受的答案将slurp文件,这可能是大文本文件的问题。更好的解决方案是IO.foreach.它是惯用的,将按字符流式传输文件:File.foreach(filename,""){|string|putsstring}包含“thisisanexample”结果的
1.错误信息:Errorresponsefromdaemon:Gethttps://registry-1.docker.io/v2/:net/http:requestcanceledwhilewaitingforconnection(Client.Timeoutexceededwhileawaitingheaders)或者:Errorresponsefromdaemon:Gethttps://registry-1.docker.io/v2/:net/http:TLShandshaketimeout2.报错原因:docker使用的镜像网址默认为国外,下载容易超时,需要修改成国内镜像地址(首先阿里
#app/models/product.rbclassProduct我从Controller调用方法1。当我运行程序时。我收到一个错误:method_missing(atlinemethod2(param2)).rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/activerecord-5.0.0/lib/active_record/relation/batches.rb:59:in`block(2levels)infind_each... 最佳答案 classProduct说明:第一个是类
我明白了defa(&block)block.call(self)end和defa()yieldselfend导致相同的结果,如果我假设有这样一个blocka{}。我的问题是-因为我偶然发现了一些这样的代码,它是否有任何区别或者是否有任何优势(如果我不使用变量/引用block):defa(&block)yieldselfend这是一个我不理解&block用法的具体案例:defrule(code,name,&block)@rules=[]if@rules.nil?@rules 最佳答案 我能想到的唯一优点就是自省(introspecti
我目前正在尝试学习RubyonRails和测试框架RSpec。assigns在此RSpec测试中做什么?describe"GETindex"doit"assignsallmymodelas@mymodel"domymodel=Factory(:mymodel)get:indexassigns(:mymodels).shouldeq([mymodel])endend 最佳答案 assigns只是检查您在Controller中设置的实例变量的值。这里检查@mymodels。 关于ruby-o
print"Enteryourpassword:"pass=STDIN.noecho(&:gets)puts"Yourpasswordis#{pass}!"输出:Enteryourpassword:input.rb:2:in`':undefinedmethod`noecho'for#>(NoMethodError) 最佳答案 一开始require'io/console'后来的Ruby1.9.3 关于ruby-为什么不能使用类IO的实例方法noecho?,我们在StackOverflow上
我正在尝试获得良好的Ruby编码风格。为防止意外调用具有相同名称的局部变量,我总是在适当的地方使用self.。但是现在我偶然发现了这个:classMyClass上面的代码导致错误privatemethodsanitize_namecalled但是当删除self.并仅使用sanitize_name时,它会起作用。这是为什么? 最佳答案 发生这种情况是因为无法使用显式接收器调用私有(private)方法,并且说self.sanitize_name是显式指定应该接收sanitize_name的对象(self),而不是依赖于隐式接收器(也是