在比较正常函数和立即函数时,我对范围感到困惑.这是一个例子:
var num=5;
var x=3;
doubleNum = function(){
num = num*x
x++;
return num;
};
console.log(doubleNum());//15
console.log(doubleNum());//60
console.log(doubleNum());//300
Run Code Online (Sandbox Code Playgroud)
这是一个普通函数,num和x是全局定义的,可由doubleNum访问,因此更新了num和x.
var num=5;
var x=3;
doubleNum = function(){
num = num*x
x++;
return num;
}();
console.log(doubleNum);//15
console.log(doubleNum);//15
console.log(doubleNum);//15
Run Code Online (Sandbox Code Playgroud)
但是,如果我定义一个立即函数并以同样的方式调用它,我得到了不同的答案.即使我希望有相同的输出我错过了必要的东西吗?或者我理解了一些错误的概念?请帮忙.提前致谢. 的jsfiddle
function init() {
var name = "Breaking Bad";
function getName() {
console.log(name);
}
function setName(newName) {
name = newName;
}
return {
getName: getName,
setName: setName
};
}
const sayMyName = init().getName; // during initialization
init().setName('Heisenberg'); // can be updated multiple times later
sayMyName(); // isn't latest i.e. NOT HeisenbergRun Code Online (Sandbox Code Playgroud)
什么可以做到getName最新name?
PS:我试过了,但是在阅读了关于内部函数,闭包等的许多答案后,却无法在stackoverflow上找到解决方案.
更新:应该注意的是,下面的问题是学术性质和核心位置的使用,或者位置数据的轮询与问题无关 - 执行此操作的正确方法始终是通过核心位置委托方法.我最初的问题最终归结为:"swift中是否有无限递归?(或尾递归)".答案是否定的.这是由于堆栈空间耗尽导致我的错误的原因.
原始问题:我遇到了一个通过闭包传递值的递归函数的问题.我是一个长期的Objective-C开发人员,但是没有在Swift编程很长时间,所以也许我错过了一些明显的东西.这是函数以及我如何调用它:
public func getLocation(completion: @escaping (CLLocationCoordinate2D?) -> ())
{
completion(self.currentLocation)
weak var weakSelf = self
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
weakSelf?.getLocation(completion: {location in
completion(weakSelf?.currentLocation)
})
}
}
LocationManager.shared.getLocation(completion: {location in
if(location != nil)
{
weakSelf?.lonLabel.text = "Lat: " + location!.latitude.description
weakSelf?.latLabel.text = "Lon: " + location!.longitude.description
}
})
Run Code Online (Sandbox Code Playgroud)
Thread 1: EXC_BAD_ACCESS (code=2, address=0x16f1b7fd0)运行一段时间后我得到的错误(描述)是这样的:
我想要完成的是将自动更新位置值传递给位置管理器对象.我正在考虑另一种方法,performSelector withObject afterDelay但在这一点上,我只是想知道为什么会崩溃?
基本上,这是一个简单的项目,涉及一个表视图,该表视图根据从api的JSON解析的数据进行更新。我相信DispatchQueue.main.async并completed: @escaping () -> ()有事情做与更新/重装tableview中,但我不知道它是如何工作的。对于这两个功能的解释将不胜感激。
import UIKit
class ViewController: UIViewController {
@IBOutlet weak var tableView: UITableView!
var heroes = [HeroStats]()
override func viewDidLoad() {
super.viewDidLoad()
fetchData {
print("Success")
}
}
func fetchData(completed: @escaping () -> ()) {
let jsonUrlString = "https://api.opendota.com/api/heroStats"
guard let url = URL(string: jsonUrlString) else { return }
URLSession.shared.dataTask(with: url) { (data, response, error) in
guard let data = data else { return }
if error == nil {
do {
let heroes …Run Code Online (Sandbox Code Playgroud) 关于定义回调的位置,我遇到了一些混乱.
function test(){
var b = 3
var fun = function(){
var printingFunction = function(){
console.log(b)
}
printingFunction()
}
return fun
}
test()() //prints 3, as expected because of closures
Run Code Online (Sandbox Code Playgroud)
但是,以下不起作用
function test(){
var b = 3
var fun = function(cb){
cb()
}
return fun
}
test()(function(){console.log(b)}) //b is not defined
Run Code Online (Sandbox Code Playgroud)
我希望由于函数作为参数传递并且之前没有定义过,它的定义发生在'fun'中,因此它可以访问b.相反,它看起来很像函数首先在其传递的范围中定义,然后THEN作为参数传递.任何想法/指针?
编辑:一些额外的指针.
someFunction("a")
Run Code Online (Sandbox Code Playgroud)
我们不可能声称"a"是一个定义.这里隐含的是"a"被赋给由参数名称so命名的变量var argumentNameInDefintion = "a".这发生在someFunction的主体中.
同样,我们不能声称{}是一个定义:someFunction({}).那么为什么会:
someFunction(function(){})
决定这function(){}是一个超越我的定义.如果是的话
var a = function(){}
someFunction(a)
Run Code Online (Sandbox Code Playgroud)
一切都会很有道理.也许它只是语言的运作方式.
所以基本上,我试图找回函数foobar返回的字符串.最初,我曾尝试从foobar返回字符串,但swift保持早期/异步返回?来自foobar.代码如下:
@IBAction func bAction(_ sender: UIButton) {
print("this prints")
foobar(completion: { (info) in
print("this does not print")
})
}
func foobar(completion: @escaping (_ info: String) -> ()) {
var info = ""
//insert code here
print("this prints too")
//insert more code here
}
Run Code Online (Sandbox Code Playgroud)
我究竟做错了什么?
谁能告诉我为什么我们使用guard let self = self?
我在阅读GCD时已经看过这段代码,我无法弄清楚那条特定的线路是做什么的.
DispatchQueue.global(qos: .userInitiated).async { [weak self] in
guard let self = self else {
return
}
// ...
}
Run Code Online (Sandbox Code Playgroud) 我正在尝试重构我的代码,并想在中返回Bool一个closure。当我尝试它时,它说它是未使用的并且不起作用。我可以用另一种方式来做,但是我要重复不想做的代码。我该怎么办。
func tableView(_ pTableView: UITableView, canEditRowAt pIndexPath: IndexPath) -> Bool {
// These lines are the one that work but would like to get rid of them
if let rowConversation = self.objectAtIndexPath(pIndexPath) as? Conversation {
if rowConversation.isGroupChat && rowConversation.expired {
return true
}
}
self.getRowConversation(pIndexPath: pIndexPath) {
// how to return true here
}
return false
}
private func getRowConversation(pIndexPath: IndexPath, completion pCompletion: () -> Void) {
if let rowConversation = self.objectAtIndexPath(pIndexPath) as? Conversation {
if …Run Code Online (Sandbox Code Playgroud) 我想知道closure在函数中是否有使用a 的方法updateView(),因此该代码not repeated用于phone和pad在下面的代码中。这里封闭应有parameters的width和height
@IBInspectable var leftImage: UIImage? {
didSet {
updateView()
}
}
func updateView() {
if let image = leftImage
{
leftViewMode = UITextField.ViewMode.always
if (UIDevice.current.userInterfaceIdiom == .phone)
{
let imageView = UIImageView(frame: CGRect(x: 0, y: 0, width: 20, height: 20))
imageView.contentMode = .scaleAspectFit
imageView.image = image
imageView.tintColor = color
leftView = imageView
}
if (UIDevice.current.userInterfaceIdiom == .pad)
{
let imageView = UIImageView(frame: CGRect(x: …Run Code Online (Sandbox Code Playgroud) 这个问题是使用局部特殊变量的注释的继续,关于如何最好地避免全局变量。据我了解,全局变量存在问题,主要是因为它们有可能干扰参照透明性。如果表达式使用其调用上下文之外的信息来更改全局值(例如,全局变量本身的先前值或任何其他外部值),则会违反透明度。在这些情况下,评估表达式在不同时间可能有不同的结果,无论是返回的值还是副作用。(但是,似乎并不是所有的全局更新都是有问题的,因为某些更新可能不依赖于任何外部信息,例如,将全局计数器重置为0)。深度嵌入计数器的常规全局方法可能类似于:
* (defparameter *x* 0)
*X*
* (defun foo ()
(incf *x*))
FOO
* (defun bar ()
(foo))
BAR
* (bar)
1
* *x*
1
Run Code Online (Sandbox Code Playgroud)
这似乎违反了参照透明性,因为它(incf *x*)依赖于外部(全局)值*x*来执行其工作。以下是通过消除全局变量来维持功能和引用透明性的尝试,但是我不相信它确实可以做到:
* (let ((x 0))
(defun inc-x () (incf x))
(defun reset-x () (setf x 0))
(defun get-x () x))
GET-X
* (defun bar ()
(inc-x))
BAR
* (defun foo ()
(bar))
FOO
* (get-x)
0
* (foo)
1
* (get-x)
1
Run Code Online (Sandbox Code Playgroud)
全局变量现在已经消失了,但是表达式似乎仍然(inc-x)具有(潜在的)副作用,并且每次调用它都会返回不同的(但未使用的)值。这是否确认对有关变量使用闭包不能解决透明性问题?
closures ×10
swift ×6
ios ×5
javascript ×3
asynchronous ×1
common-lisp ×1
function ×1
recursion ×1