@@ -224,12 +224,20 @@ final class CodeFileDocument: NSDocument, ObservableObject {
224224 // MARK: - External Changes
225225
226226 /// Handle the notification that the represented file item changed.
227+ ///
228+ /// We check if a file has been modified and can be read again to display to the user.
229+ /// To determine if a file has changed, we check the modification date. If it's different from the stored one,
230+ /// we continue.
231+ /// To determine if we can reload the file, we check if the document has outstanding edits. If not, we reload the
232+ /// file.
227233 override func presentedItemDidChange( ) {
228- // Grab the file saved date
229234 if fileModificationDate != getModificationDate ( ) {
230235 guard isDocumentEdited else {
231236 fileModificationDate = getModificationDate ( )
232237 if let fileURL, let fileType {
238+ // This blocks the presented item thread intentionally. If we don't wait, we'll receive more updates
239+ // that the file has changed and we'll end up dispatching multiple reads.
240+ // The presented item thread expects this operation to by synchronous anyways.
233241 DispatchQueue . main. asyncAndWait {
234242 try ? self . read ( from: fileURL, ofType: fileType)
235243 }
@@ -241,6 +249,10 @@ final class CodeFileDocument: NSDocument, ObservableObject {
241249 super. presentedItemDidChange ( )
242250 }
243251
252+ /// Helper to find the last modified date of the represented file item.
253+ ///
254+ /// Different from `NSDocument.fileModificationDate`. This returns the *current* modification date, whereas the
255+ /// alternative stores the date that existed when we last read the file.
244256 private func getModificationDate( ) -> Date ? {
245257 guard let path = fileURL? . absolutePath else { return nil }
246258 return try ? FileManager . default. attributesOfItem ( atPath: path) [ . modificationDate] as? Date
0 commit comments