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定义,它将正常工作。但是我需要它,因为另一个函数需要访问它的值。 我真的不确定导致这个问题的原因,如果你有线索,请帮忙。
答案 0 :(得分:27)
使用闭包而不是函数:
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
}
})
答案 1 :(得分:11)
以下是游戏中的基本原则:(来自Apple的文档:https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/Closures.html#//apple_ref/doc/uid/TP40014097-CH11-ID103)
&#34;函数中引入的全局函数和嵌套函数实际上是闭包的特例。闭包采用以下三种形式之一:
即没关系
func someFunc() {
func nestFunc() {}
}
但这不是
func someFunc() {
func nestFunc() {
func nestedFunc2() { }
}
}
如果你在Xcode中看到这个,第三个函数(func nestedFunc2)会给你错误&#34;不能从另一个本地函数中引用本地函数&#34;
top函数(func someFunc)是一个全局范围函数,它们就像常规函数/方法一样工作。
第二个函数(func nestFunc)是一个嵌套函数,它是一个深层的命名闭包,可以捕获其父全局函数的范围。
嵌套函数可以捕获全局函数的范围,但不另一个嵌套函数的范围。
这就是为什么我们需要一个闭包,即
func someFunc() {
func nestFunc() {
let strictClosure = { () -> () in
//this is where you write the code
}
}
}
答案 2 :(得分:2)
更线性且更易读的流程是将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)
}
}
}
并在调用first_name
时定义的闭包中对problemFunc
进行实际分配:
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
}
}
})