Swift - NSIndex forRow inSection Initializer
Posted
技术标签:
【中文标题】Swift - NSIndex forRow inSection Initializer【英文标题】: 【发布时间】:2014-10-07 15:29:43 【问题描述】:我有以下代码:
var path = NSIndexPath(forRow: index, inSection:0);
我收到一个编译器警告:
Extra Argument 'inSection' in call
为什么?我在这里的文档中看到了初始化程序:
https://developer.apple.com/library/ios/documentation/UIKit/Reference/NSIndexPath_UIKitAdditions/index.html#//apple_ref/occ/clm/NSIndexPath/indexPathForRow:inSection:
我导入了 UIKit,甚至尝试做类似的事情:
var path = UIKit.NSIndexPath(forRow: index, inSection:0);
我在这里误会了什么?
编辑:
var index = 0;
for (key, value) in map!
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), (index) in
//some code
dispatch_async(dispatch_get_main_queue(), (index) in
println("reloadRow row=" + String(index) + ",inSection:0");
var path = NSIndexPath(forRow: index, inSection:0);
self.tableView.reloadRowsAtIndexPaths([path], withRowAnimation: UITableViewRowAnimation.Automatic);
);
);
index++;
【问题讨论】:
index
是如何定义的?
@MikeS 它是一个整数。 var index = 0;
等一下,让我把整个代码块贴出来,因为也许我使用闭包的方式与此有关。
@MikeS 好的,我现在有完整的代码,也许我没有正确使用闭包。
【参考方案1】:
index
可能无法被编译器识别。在 Playground 中尝试代码:
import UIKit
let index = 3
var path = NSIndexPath(forRow: index, inSection: 0)
作品
import UIKit
var path = NSIndexPath(forRow: index, inSection: 0)
错误:Extra Argument 'inSection' in call
这意味着您的index
变量定义不明确。或者您应该尝试Clean
并删除派生数据。
编辑:
删除 dispatch_async
中的 index
声明,它与您的 index
变量冲突。
dispatch_async(dispatch_get_main_queue(), _ in
println("reloadRow row=" + String(index) + ",inSection:0");
var path = NSIndexPath(forRow: index, inSection:0);
self.tableView.reloadRowsAtIndexPaths([path], withRowAnimation: UITableViewRowAnimation.Automatic);
);
奖励:您应该使用带有闭包的 Swift 快捷方式。 (尾随闭包+无参数)因为它:
dispatch_async(dispatch_get_main_queue())
println("reloadRow row=" + String(index) + ",inSection:0");
var path = NSIndexPath(forRow: index, inSection:0);
self.tableView.reloadRowsAtIndexPaths([path], withRowAnimation: UITableViewRowAnimation.Automatic);
编辑:您在第一次异步调度中犯了同样的错误。当您声明 dispatch_async
并编写 index in
时,这与声明具有索引作为参数的函数相同。这是一个可变范围问题(您应该阅读此内容)。我更新了最终代码。
var index = 0
for (key, value) in map!
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0))
//some code
dispatch_async(dispatch_get_main_queue())
println("reloadRow row=" + String(index) + ",inSection:0");
var path = NSIndexPath(forRow: index, inSection:0);
self.tableView.reloadRowsAtIndexPaths([path], withRowAnimation: UITableViewRowAnimation.Automatic);
index++
【讨论】:
我认为你完全正确。我只是举了一个更完整的例子,它与我如何使用闭包有关吗? 所以在您的代码中,我看到您实际上在dispatch_async
中定义了另一个名为index
的变量。您不必这样做,范围内的所有变量都可以通过闭包访问。
所以这绝对修复了编译器错误。附带说明一下,当使用这样的闭包时,您知道为什么 index 的值始终是我的字典中元素的数量吗?我熟悉 javascript 闭包,它会在范围内复制变量的当前值,但 swift 似乎并非如此。
因为你在第一次异步调度中犯了同样的错误。当您声明dispatch_async
并执行 index in
时,这与声明一个以index
作为参数的函数相同。这是一个变量范围问题。我更新了最终代码。【参考方案2】:
要在异步块中保留 当前 index
值,
你应该使用Closure Expression Syntax。可以像这样立即调用。
var index = 0
for (key, value) in map!
(idx) in // <- this is fixed value `index`
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0))
// some code...
dispatch_async(dispatch_get_main_queue())
var path = NSIndexPath(forRow: idx, inSection:0);
self.tableView.reloadRowsAtIndexPaths([path], withRowAnimation: UITableViewRowAnimation.Automatic);
(index++)
OP中的代码可以翻译成JavaScript:
var index = 0;
while(...)
dispatch_async(GLOBAL_QUEUE, function(index)
//some code
dispatch_async(MAIN_QUEUE, function(index)
var path = new NSIndexPath(index, 0);
self.tableView.reloadRowsAtIndexPaths([path], ANIM_AUTO);
);
);
index++;
你看到了吗?因为dispatch_async
的回调不接收任何参数,所以你的innerindex
将是undefined
。
相反,您应该编写如下代码:
var index = 0;
while(...)
(function(idx)
dispatch_async(GLOBAL_QUEUE, function()
//some code
dispatch_async(MAIN_QUEUE, function()
var path = new NSIndexPath(idx, 0);
self.tableView.reloadRowsAtIndexPaths([path], ANIM_AUTO);
);
);
)(index++);
我认为,(function(val) ... )(val)
成语在 JavaScript 中很常见,不是吗?
【讨论】:
为什么这与我所做的不同?抱歉,我对 Swift 比较陌生,但是如果您想进行一些比较,我确实非常了解 Javascript 闭包。 我不明白为什么内部匿名函数在调用时无法访问 index 的值。 好的,我了解您现在想要表达的意思。感谢您抽出宝贵时间。 因为index
“变量名”被回调函数的参数覆盖了。
感谢您对我糟糕的英语技能的耐心等待 :)【参考方案3】:
对我来说,Xcode 8.3 和 Swift 3 的工作方式如下:
let indexPath = NSIndexPath(row: row, section: section)
【讨论】:
以上是关于Swift - NSIndex forRow inSection Initializer的主要内容,如果未能解决你的问题,请参考以下文章
一日一技:炸掉你的内存—— itertools.tee 的缺陷
swift 简单的javascript repl in swift