swift - 为什么在类中需要声明 self 的结构中不需要声明 self ?

标签 swift

为什么要声明self在类中需要的结构中不需要?我不知道是否还有其他例子说明了这种情况,但在转义闭包的情况下,确实如此。如果闭包是非可选的(因此是非转义的),则不需要声明 self在两者中的任何一个。

class SomeClass {
    let someProperty = 1
    
    func someMethod(completion: (() -> Void)?) {}
    
    func anotherMethod() {
        someMethod {
            print(self.someProperty) // declaring self is required
        }
    }
}

struct SomeStruct {
    let someProperty = 1
    
    func someMethod(completion: (() -> Void)?) {}
    
    func anotherMethod() {
        someMethod {
            print(someProperty) // declaring self is not required
        }
    }
}

最佳答案

包含self的目的在带有引用类型的转义闭包(无论是可选闭包还是明确标记为 @escaping 的闭包)中使用属性时,可以使捕获语义明确。如果我们删除 self,编译器会警告我们引用:

Reference to property 'someProperty' in closure requires explicit use of 'self' to make capture semantics explicit.


但是,结构没有模糊的捕获语义。您总是在转义闭包内处理副本。它只对引用类型不明确,您需要 self明确可能引入强引用循环的位置,您正在引用哪个实例等。

顺便说一下,对于类类型,引用 self与属性结合并不是使捕获语义明确的唯一方法。例如,您可以使用“捕获列表”明确您的意图,或者:
  • 仅捕获属性(property):
     class SomeClass {
         var someProperty = 1
    
         func someMethod(completion: @escaping () -> Void) { ... }
    
         func anotherMethod() {
             someMethod { [someProperty] in    // this captures the property, but not `self`
                 print(someProperty)
             }
         }
     }
    
  • 或捕获 self :
     class SomeClass {
         var someProperty = 1
    
         func someMethod(completion: @escaping () -> Void) { ... }
    
         func anotherMethod() {
             someMethod { [self] in            // this explicitly captures `self`
                 print(someProperty)
             }
         }
     }
    

  • 这两种方法还可以明确您正在捕获的内容。

    关于swift - 为什么在类中需要声明 self 的结构中不需要声明 self ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64233385/

    相关文章:

    ios - 在不禁用 AutoLayout 的情况下更改按钮大小

    ios - 使用 Eureka 框架选择多行

    ios - 在 Swift 中将协议(protocol)类型作为参数传递

    ios - 一旦在 Swift 中达到最大高度,UITextView 就会变得可滚动

    ios - 动态 Tableviewcell 中的按钮不可点击

    ios - 无法将类型 '(NSError!, SPTSession!) -> Void' 的值转换为预期参数类型 'SPTAuthCallback!'

    ios - UICollectionView 页眉和页脚 View

    ios - 在 Swift 中将 Int 转换为 Float 会丢失大数字的精度

    ios - 在整个应用程序上设置日历类型

    swift - 使用 api 调用发送 JSON 数组并存储在数据库中