Swift3中结构和类异步变异的不同过程
在struct类型中,在异步进程中修改self会产生如下错误Swift3中结构和类异步变异的不同过程,swift,class,asynchronous,struct,swift3,Swift,Class,Asynchronous,Struct,Swift3,在struct类型中,在异步进程中修改self会产生如下错误 闭包无法隐式捕获变异的自我 如果我将结构更改为类类型,错误就会消失。 当以异步方式改变self时,struct和class之间有什么区别 struct Media { static let loadedDataNoti = "loadedDataNotification" let imagePath: String let originalPath: String let description: String var imageDa
闭包无法隐式捕获变异的自我
如果我将结构更改为类类型,错误就会消失。
当以异步方式改变self时,struct
和class
之间有什么区别
struct Media {
static let loadedDataNoti = "loadedDataNotification"
let imagePath: String
let originalPath: String
let description: String
var imageData: Data?
let tag: String
var likeCount: Int?
var commentCount: Int?
var username: String?
var delegate: MediaDelegate?
public init(imagePath: String, originalPath: String, description: String, tag: String, imageData: Data? = nil) {
self.imagePath = imagePath
self.originalPath = originalPath
self.description = description
self.tag = tag
if imageData != nil {
self.imageData = imageData
} else {
loadImageData()
}
}
mutating func loadImageData() {
if let url = URL(string: imagePath) {
Data.getDataFromUrl(url: url, completion: { (data, response, error) in
if (error != nil) {
print(error.debugDescription)
return
}
if data != nil {
self.imageData = data! // Error: closure cannot implicitly captured a mutating self
NotificationCenter.default.post(name: NSNotification.Name(rawValue: Media.loadedDataNoti), object: data)
}
})
}
}
当您对值类型的实例(如结构)进行变异时,您在概念上是将其替换为同一类型的新实例,即:
myMedia.mutatingFuncToLoadImageData()
…可以被认为是这样做的:
myMedia = Media(withLoadedData: theDownloadedData)
struct S {
var name = "matt"
}
var s = S()
s.name = "me"
…除非你看不到代码中的赋值
实际上,您正在替换调用上的mutating
函数的实例。在这种情况下,myMedia
。正如您可能意识到的,为了使其工作,变异必须在变异函数的末尾完成,否则您的实例在调用变异函数后将继续更改
您正在将对self
的引用传递给一个异步函数,该函数将在变异函数结束后尝试变异您的实例
您可以通过执行以下操作来编译代码
var myself = self // making a copy of self
let closure = {
myself.myThing = "thing"
}
但这只会更改变量的值,而不会影响函数之外的任何内容。当您更改值类型的实例(如结构)时,您在概念上用相同类型的新实例替换它,即:
myMedia.mutatingFuncToLoadImageData()
…可以被认为是这样做的:
myMedia = Media(withLoadedData: theDownloadedData)
struct S {
var name = "matt"
}
var s = S()
s.name = "me"
…除非你看不到代码中的赋值
实际上,您正在替换调用上的mutating
函数的实例。在这种情况下,myMedia
。正如您可能意识到的,为了使其工作,变异必须在变异函数的末尾完成,否则您的实例在调用变异函数后将继续更改
您正在将对self
的引用传递给一个异步函数,该函数将在变异函数结束后尝试变异您的实例
您可以通过执行以下操作来编译代码
var myself = self // making a copy of self
let closure = {
myself.myThing = "thing"
}
但这只会更改变量的值,而不会影响函数之外的任何内容。结构是一种值类型。结构突变是如何工作的?它的工作原理是创建一个全新的结构并用它替换原来的结构。即使在这样简单的情况下:
myMedia = Media(withLoadedData: theDownloadedData)
struct S {
var name = "matt"
}
var s = S()
s.name = "me"
。。。实际上,您正在用另一个实例替换一个实例-这就是为什么必须将S
声明为var
才能执行此操作的原因
这样,当你将一个Stutt的<代码>自我/代码>捕获到一个异步执行的闭包中并要求对它进行突变时,你威胁会在将来某个时间出现,并突然撕开现有的结构,并在执行这段代码的过程中用另一个结构替换它。这是一个不连贯的概念,编译器正确地阻止了您。这是不连贯的,尤其是因为你怎么知道这个相同的
自我
在那个时候还会存在?中间的突变可能已经破坏并取代了它
因此,这是合法的:
struct S {
var name = "matt"
mutating func change() {self.name = "me"}
}
但这不是:
func delay(_ delay:Double, closure:@escaping ()->()) {
let when = DispatchTime.now() + delay
DispatchQueue.main.asyncAfter(deadline: when, execute: closure)
}
struct S {
var name = "matt"
mutating func change() {delay(1) {self.name = "me"}} // error
}
结构是一种值类型。结构突变是如何工作的?它的工作原理是创建一个全新的结构并用它替换原来的结构。即使在这样简单的情况下:
myMedia = Media(withLoadedData: theDownloadedData)
struct S {
var name = "matt"
}
var s = S()
s.name = "me"
。。。实际上,您正在用另一个实例替换一个实例-这就是为什么必须将S
声明为var
才能执行此操作的原因
这样,当你将一个Stutt的<代码>自我/代码>捕获到一个异步执行的闭包中并要求对它进行突变时,你威胁会在将来某个时间出现,并突然撕开现有的结构,并在执行这段代码的过程中用另一个结构替换它。这是一个不连贯的概念,编译器正确地阻止了您。这是不连贯的,尤其是因为你怎么知道这个相同的
自我
在那个时候还会存在?中间的突变可能已经破坏并取代了它
因此,这是合法的:
struct S {
var name = "matt"
mutating func change() {self.name = "me"}
}
但这不是:
func delay(_ delay:Double, closure:@escaping ()->()) {
let when = DispatchTime.now() + delay
DispatchQueue.main.asyncAfter(deadline: when, execute: closure)
}
struct S {
var name = "matt"
mutating func change() {delay(1) {self.name = "me"}} // error
}
使此代码在
中的函数变为mutating
。像这样mutating func(){//your code}
。函数声明为mutating
?@尽管我尝试过。但是结果是一样的。发布更多的代码。添加完整的代码。使此代码所在的函数发生变化。像这样mutating func(){//your code}
。函数声明为mutating
?@尽管我尝试过。但是结果是一样的。发布更多的代码。添加完整的代码。问题集中在引用和复制的不同方式上。谢谢。问题集中在不同的参考和复制方式上。谢谢