Skip to content

Commit a73d2e5

Browse files
Fix WorkspaceDocument Leak (#1808)
1 parent 32e7190 commit a73d2e5

File tree

55 files changed

+577
-453
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

55 files changed

+577
-453
lines changed

CodeEdit.xcodeproj/project.pbxproj

Lines changed: 73 additions & 38 deletions
Large diffs are not rendered by default.

CodeEdit.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved

Lines changed: 8 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
2-
"originHash" : "f3dd40f19b32a2b522dee7a1e94ceb60afbdb1a028938883adffc7328ef9d804",
2+
"originHash" : "a33fcca819dee4c816b1474e19017510b1d62b170c921187042e0675d3f4b0b3",
33
"pins" : [
44
{
55
"identity" : "anycodable",
@@ -31,10 +31,10 @@
3131
{
3232
"identity" : "codeeditsourceeditor",
3333
"kind" : "remoteSourceControl",
34-
"location" : "https://github.com/CodeEditApp/CodeEditSourceEditor.git",
34+
"location" : "https://github.com/CodeEditApp/CodeEditSourceEditor",
3535
"state" : {
36-
"revision" : "cf85789d527d569e94edfd674c5ac8071b244dd9",
37-
"version" : "0.7.3"
36+
"revision" : "4e014f71d7be053ea8d05f6c0e45be268f9a0d64",
37+
"version" : "0.7.4"
3838
}
3939
},
4040
{
@@ -136,15 +136,6 @@
136136
"version" : "1.3.0"
137137
}
138138
},
139-
{
140-
"identity" : "mainoffender",
141-
"kind" : "remoteSourceControl",
142-
"location" : "https://github.com/mattmassicotte/MainOffender",
143-
"state" : {
144-
"revision" : "8de872d9256ff7f9913cbc5dd560568ab164be45",
145-
"version" : "0.2.1"
146-
}
147-
},
148139
{
149140
"identity" : "processenv",
150141
"kind" : "remoteSourceControl",
@@ -258,17 +249,17 @@
258249
"kind" : "remoteSourceControl",
259250
"location" : "https://github.com/ChimeHQ/TextFormation",
260251
"state" : {
261-
"revision" : "f6faed6abd768ae95b70d10113d4008a7cac57a7",
262-
"version" : "0.8.2"
252+
"revision" : "b1ce9a14bd86042bba4de62236028dc4ce9db6a1",
253+
"version" : "0.9.0"
263254
}
264255
},
265256
{
266257
"identity" : "textstory",
267258
"kind" : "remoteSourceControl",
268259
"location" : "https://github.com/ChimeHQ/TextStory",
269260
"state" : {
270-
"revision" : "8883fa739aa213e70e6cb109bfbf0a0b551e4cb5",
271-
"version" : "0.8.0"
261+
"revision" : "8dc9148b46fcf93b08ea9d4ef9bdb5e4f700e008",
262+
"version" : "0.9.0"
272263
}
273264
}
274265
],

CodeEdit/AppDelegate.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ final class AppDelegate: NSObject, NSApplicationDelegate, ObservableObject {
1313
private let updater = SoftwareUpdater()
1414

1515
@Environment(\.openWindow)
16-
private var openWindow
16+
var openWindow
1717

1818
func applicationDidFinishLaunching(_ notification: Notification) {
1919
setupServiceContainer()
@@ -209,8 +209,8 @@ final class AppDelegate: NSObject, NSApplicationDelegate, ObservableObject {
209209
defaults.removeObject(forKey: "openInCEFiles")
210210
}
211211

212-
DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
213-
self.checkForFilesToOpen()
212+
DispatchQueue.main.asyncAfter(deadline: .now() + 1) { [weak self] in
213+
self?.checkForFilesToOpen()
214214
}
215215
}
216216

CodeEdit/Features/CEWorkspace/Models/CEWorkspaceFile.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -85,11 +85,11 @@ final class CEWorkspaceFile: Codable, Comparable, Hashable, Identifiable, Editor
8585
/// Returns a parent ``CEWorkspaceFile``.
8686
///
8787
/// If the item already is the top-level ``CEWorkspaceFile`` this returns `nil`.
88-
var parent: CEWorkspaceFile?
88+
weak var parent: CEWorkspaceFile?
8989

9090
private let fileDocumentSubject = PassthroughSubject<CodeFileDocument?, Never>()
9191

92-
var fileDocument: CodeFileDocument? {
92+
weak var fileDocument: CodeFileDocument? {
9393
didSet {
9494
fileDocumentSubject.send(fileDocument)
9595
}

CodeEdit/Features/CEWorkspace/Models/CEWorkspaceFileManager.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -387,6 +387,7 @@ final class CEWorkspaceFileManager {
387387
}
388388

389389
deinit {
390+
fsEventStream?.cancel()
390391
observers.removeAllObjects()
391392
}
392393
}

CodeEdit/Features/CEWorkspace/Models/CEWorkspaceSettings.swift

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -10,20 +10,12 @@ import Combine
1010

1111
/// The CodeEdit workspace settings model.
1212
final class CEWorkspaceSettings: ObservableObject {
13-
@ObservedObject private var workspace: WorkspaceDocument
1413
@Published public var preferences: CEWorkspaceSettingsData = .init()
1514

16-
private var storeTask: AnyCancellable!
15+
private var storeTask: AnyCancellable?
1716
private let fileManager = FileManager.default
1817

19-
private var folderURL: URL? {
20-
guard let workspaceURL = workspace.fileURL else {
21-
return nil
22-
}
23-
24-
return workspaceURL
25-
.appendingPathComponent(".codeedit", isDirectory: true)
26-
}
18+
private(set) var folderURL: URL?
2719

2820
private var settingsURL: URL? {
2921
folderURL?
@@ -32,15 +24,23 @@ final class CEWorkspaceSettings: ObservableObject {
3224
}
3325

3426
init(workspaceDocument: WorkspaceDocument) {
35-
self.workspace = workspaceDocument
36-
27+
folderURL = workspaceDocument.fileURL?.appendingPathComponent(".codeedit", isDirectory: true)
3728
loadSettings()
3829

3930
self.storeTask = self.$preferences.throttle(for: 2.0, scheduler: RunLoop.main, latest: true).sink {
4031
try? self.savePreferences($0)
4132
}
4233
}
4334

35+
func cleanUp() {
36+
storeTask?.cancel()
37+
storeTask = nil
38+
}
39+
40+
deinit {
41+
cleanUp()
42+
}
43+
4444
/// Load and construct ``CEWorkspaceSettings`` model from `.codeedit/settings.json`
4545
private func loadSettings() {
4646
if let settingsURL = settingsURL {

CodeEdit/Features/CodeEditUI/Views/ToolbarBranchPicker.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@ import Combine
1111

1212
/// A view that pops up a branch picker.
1313
struct ToolbarBranchPicker: View {
14-
private var workspaceFileManager: CEWorkspaceFileManager?
15-
private var sourceControlManager: SourceControlManager?
14+
private weak var workspaceFileManager: CEWorkspaceFileManager?
15+
private weak var sourceControlManager: SourceControlManager?
1616

1717
@Environment(\.controlActiveState)
1818
private var controlActive

CodeEdit/Features/Commands/Views/QuickActionsView.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ struct QuickActionsView: View {
3131

3232
func callHandler(command: Command) {
3333
closePalette()
34-
command.closureWrapper.call()
34+
command.closureWrapper()
3535
selectedItem = nil
3636
state.commandQuery = ""
3737
state.filteredCommands = []

CodeEdit/Features/Documents/Controllers/CodeEditSplitViewController.swift

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@ final class CodeEditSplitViewController: NSSplitViewController {
1414
static let snapWidth: CGFloat = 272
1515
static let minSnapWidth: CGFloat = snapWidth - 10
1616

17-
private var workspace: WorkspaceDocument
18-
private var navigatorViewModel: NavigatorSidebarViewModel
17+
private weak var workspace: WorkspaceDocument?
18+
private weak var navigatorViewModel: NavigatorSidebarViewModel?
1919
private weak var windowRef: NSWindow?
2020
private unowned var hapticPerformer: NSHapticFeedbackPerformer
2121

@@ -47,12 +47,20 @@ final class CodeEditSplitViewController: NSSplitViewController {
4747
return
4848
}
4949

50+
guard let workspace,
51+
let navigatorViewModel,
52+
let editorManager = workspace.editorManager,
53+
let statusBarViewModel = workspace.statusBarViewModel,
54+
let utilityAreaModel = workspace.utilityAreaModel else {
55+
return
56+
}
57+
5058
splitView.translatesAutoresizingMaskIntoConstraints = false
5159

5260
let settingsView = SettingsInjector {
5361
NavigatorAreaView(workspace: workspace, viewModel: navigatorViewModel)
5462
.environmentObject(workspace)
55-
.environmentObject(workspace.editorManager)
63+
.environmentObject(editorManager)
5664
}
5765

5866
let navigator = NSSplitViewItem(sidebarWithViewController: NSHostingController(rootView: settingsView))
@@ -64,12 +72,12 @@ final class CodeEditSplitViewController: NSSplitViewController {
6472
addSplitViewItem(navigator)
6573

6674
let workspaceView = SettingsInjector {
67-
WindowObserver(window: windowRef) {
75+
WindowObserver(window: WindowBox(value: windowRef)) {
6876
WorkspaceView()
6977
.environmentObject(workspace)
70-
.environmentObject(workspace.editorManager)
71-
.environmentObject(workspace.statusBarViewModel)
72-
.environmentObject(workspace.utilityAreaModel)
78+
.environmentObject(editorManager)
79+
.environmentObject(statusBarViewModel)
80+
.environmentObject(utilityAreaModel)
7381
}
7482
}
7583

@@ -82,7 +90,7 @@ final class CodeEditSplitViewController: NSSplitViewController {
8290
let inspectorView = SettingsInjector {
8391
InspectorAreaView(viewModel: InspectorAreaViewModel())
8492
.environmentObject(workspace)
85-
.environmentObject(workspace.editorManager)
93+
.environmentObject(editorManager)
8694
}
8795

8896
let inspector = NSSplitViewItem(inspectorWithViewController: NSHostingController(rootView: inspectorView))
@@ -98,6 +106,8 @@ final class CodeEditSplitViewController: NSSplitViewController {
98106
override func viewWillAppear() {
99107
super.viewWillAppear()
100108

109+
guard let workspace else { return }
110+
101111
let navigatorWidth = workspace.getFromWorkspaceState(.splitViewWidth) as? CGFloat
102112
splitView.setPosition(navigatorWidth ?? Self.minSidebarWidth, ofDividerAt: 0)
103113

@@ -178,16 +188,16 @@ final class CodeEditSplitViewController: NSSplitViewController {
178188
let panel = splitView.subviews[0]
179189
let width = panel.frame.size.width
180190
if width > 0 {
181-
workspace.addToWorkspaceState(key: .splitViewWidth, value: width)
191+
workspace?.addToWorkspaceState(key: .splitViewWidth, value: width)
182192
}
183193
}
184194
}
185195

186196
func saveNavigatorCollapsedState(isCollapsed: Bool) {
187-
workspace.addToWorkspaceState(key: .navigatorCollapsed, value: isCollapsed)
197+
workspace?.addToWorkspaceState(key: .navigatorCollapsed, value: isCollapsed)
188198
}
189199

190200
func saveInspectorCollapsedState(isCollapsed: Bool) {
191-
workspace.addToWorkspaceState(key: .inspectorCollapsed, value: isCollapsed)
201+
workspace?.addToWorkspaceState(key: .inspectorCollapsed, value: isCollapsed)
192202
}
193203
}

0 commit comments

Comments
 (0)