无法使用本地函数捕获本地函数(swift)
var first_name = ""
func problemFunc() {
FBRequestConnection.startForMeWithCompletionHandler { (connection: FBRequestConnection!, result: AnyObject!, error: NSError!) -> Void in
if let fbGraphUserDict = result as? Dictionary<String, AnyObject>{
first_name = fbGraphUserDict["first_name"] as NSString
println(first_name)
}
}
}
PFFacebookUtils.logInWithPermissions(permissions, {
(user: PFUser!, error: NSError!) -> Void in
if user == nil {
NSLog("Uh oh. The user cancelled the Facebook login.")
} else if user.isNew {
NSLog("User signed up and logged in through Facebook!")
} else {
NSLog("User logged in through Facebook!")
problemFunc() // error is here
}
})
此代码位于@Ibaction按钮内。我无法构建,因为调用problemFunc()会触发此帖子标题中的错误消息。如果我移动problemFunc中的first_name var定义,它将正常工作。但我需要它,因为另一个功能需要访问它的价值。 我真的不确定导致此问题的原因,如果您有线索,请帮助。无法使用本地函数捕获本地函数(swift)
使用闭包,而不是一个功能:
var first_name = ""
let problemFunc = {() ->() in
FBRequestConnection.startForMeWithCompletionHandler { (connection: FBRequestConnection!, result: AnyObject!, error: NSError!) -> Void in
if let fbGraphUserDict = result as? Dictionary<String, AnyObject>{
first_name = fbGraphUserDict["first_name"] as NSString
println(first_name)
}
}
}
PFFacebookUtils.logInWithPermissions(permissions, {
(user: PFUser!, error: NSError!) -> Void in
if user == nil {
NSLog("Uh oh. The user cancelled the Facebook login.")
} else if user.isNew {
NSLog("User signed up and logged in through Facebook!")
} else {
NSLog("User logged in through Facebook!")
problemFunc() // error is here
}
})
@fluidsonic答案应该解决的问题。但是请注意,你正在做一些意大利面代码,因为你正在修改一个闭包捕获的变量,并在另一个函数的上下文中执行。如果您需要调试,那么很难跟踪,而且更一般地难以追踪何时以及如何修改该变量。
更线性的和更好的可读流是定义problemFunc
作为函数以一个函数作为参数,调用该函数,而不是在first_name
变量直接设置值:
let problemFunc = { (callback: (String -> Void) ->()) in
FBRequestConnection.startForMeWithCompletionHandler { (connection: FBRequestConnection!, result: AnyObject!, error: NSError!) -> Void in
if let fbGraphUserDict = result as? Dictionary<String, AnyObject>{
let first_name = fbGraphUserDict["first_name"] as NSString
callback(first_name) // << here you call the callback passing the `first_name` local variable
println(first_name)
}
}
}
,并执行实际调用problemFunc
当分配到你定义一个封闭first_name
:
PFFacebookUtils.logInWithPermissions(permissions, {
(user: PFUser!, error: NSError!) -> Void in
if user == nil {
NSLog("Uh oh. The user cancelled the Facebook login.")
} else if user.isNew {
NSLog("User signed up and logged in through Facebook!")
} else {
NSLog("User logged in through Facebook!")
problemFunc { (name: String) -> Void in
first_name = name
}
}
})
谢谢,也会尝试那 – 2014-10-07 15:43:09
下面是游戏的基本原则:(来自苹果的文档:https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/Closures.html#//apple_ref/doc/uid/TP40014097-CH11-ID103)
“函数中引入的全局函数和嵌套函数实际上是闭包的特例。关闭采取以下三种形式之一:
- 全局函数是具有名称并且不捕获任何值的闭包。
- 嵌套函数是具有名称并可从其封闭函数捕获值的闭包。
- 闭合表达式是写在一个轻量级的语法,可以从他们的周围上下文捕捉值无名倒闭。”
即这是确定
func someFunc() {
func nestFunc() {}
}
但这不是
func someFunc() {
func nestFunc() {
func nestedFunc2() { }
}
}
如果你在Xcode中查看这个函数,第三个函数(func nestedFunc2)会给你错误:“不能用本地函数捕获另一个局部函数f联合“
*函数(func someFunc)是一个全局作用域函数和那些像常规函数/方法一样工作。
第二个函数(func nestFunc)是一个嵌套函数它是一个深度为一级的命名闭包,可以捕获其父级全局函数的作用域。
嵌套函数,可以捕获全局函数的作用域但不是另一个嵌套函数的作用域。
这就是为什么我们需要一个封闭即
func someFunc() {
func nestFunc() {
let strictClosure = {() ->() in
//this is where you write the code
}
}
}
正好! +1一路 – 2015-01-17 19:00:48
精湛的解释。我不知道发生了什么事,但是你让它很容易理解。 +1 – TaylorAllred 2015-04-17 01:56:10
感谢,工作原理,但由于某些原因,我不得不删除: - >() – 2014-10-07 15:42:43
非常感谢!好主意,以避免这个丑陋的东西 – iiFreeman 2014-12-17 14:54:08