【问题标题】:Swift passing self as argument in class initSwift 在类 init 中将 self 作为参数传递
【发布时间】:2021-10-20 10:54:08
【问题描述】:

我的 Swift 项目中有一个“用户”类。由于这个类必须提供大量功能,我想将任务委托给存储在 User 类中作为实例变量的其他类。例如,每个用户都会有一个“Feed Manager”类的实例作为实例变量存储在其中。

这可以用其他语言完成(我先用 Python 构建了它),但我不知道这是否可以在 swift 中实现。具体来说,我需要将 User self 传递到 User init 中的 Feed Manager 实例中(以唯一地链接实例),但 Swift 正在抛出“在初始化所有存储的属性之前的 self user”。有什么办法可以解决这个问题并实现所需的功能?

代码:

class User: Identifiable, Equatable {
    let id = UUID()
    let feeds: FeedManager
    var username: String
    var firstname: String
    var lastname: String
    var fullname: String
    var bio: String
    
    init(username: String, firstname: String, lastname: String, fullname: String, bio: String) {
        self.username = username
        self.lastname = lastname
        self.firstname = firstname
        self.fullname = firstname + " " + lastname
        self.bio = bio
        
        self.feeds = FeedManager(user: self)
        
    }
    static func == (user1: User, user2: User) -> Bool {
        return user1.id == user2.id
    }
    
}

class FeedManager {
    let user: User
    var currentInvit:       [PostData] = []
    var currentHost:        [PostData] = []
    var currentAttend:      [PostData] = []
    var currentDismissed:   [PostData] = []
    var pastHost:           [PostData] = []
    var pastAttend:         [PostData] = []
    
    init(user: User) {
        self.user = user
    }
}

【问题讨论】:

  • 您可以通过lazy var 这样做。 lazy var feeds: FeedsManager = { FeedManager(user: self) }()?但由于您可能不清楚您想用 FeedManager 做什么,因此架构可能会有所不同。
  • 如果 FeedManager 是 User 中的一个属性,那么它不需要一个 User 作为属性,移除这种双重耦合将改善架构。题外话:fullName 是您的 init 方法中的一个参数,但您不使用它
  • 是的,我注意到全名了哈哈
  • 我需要在 Feed 管理器中使用 self,因为 Feed 管理器中的某些方法需要引用存储在 User 对象中的数据(或者我可能作为实例变量存储在 User 中的其他对象)
  • 还要注意UserFeedManager形成一个强引用循环(所有权循环),即内存泄漏。

标签: swift class init self


【解决方案1】:

您可以使用惰性 var 方法,将 feeds 设为可选项或将其声明为隐式展开的可选项。您初始化所有存储的属性,然后设置 FeedManager 使用 self 对其进行初始化。


class User {
    let id = UUID()
    var feeds: FeedManager!   // implicitly unwrapped
    //var feeds: FeedManager?
    var name: String
    
    init(name: String) {
        self.name = name
        feeds = FeedManager(user: self)
    }
}

class FeedManager {
    weak var user: User?
    var currentInvit: [String] = []
    
    init(user: User) {
        self.user = user
    }
}

【讨论】:

    猜你喜欢
    • 2015-06-20
    • 1970-01-01
    • 1970-01-01
    • 2022-01-16
    • 2015-03-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-07
    相关资源
    最近更新 更多