DrRocket
DrRocket

Reputation: 235

Swfit FileManager crashes with EXC_BAD_ACCESS when copying a file a second time

I'm writing a MacOS application with a process that creates a temp folder in the Application Support directory, generates a few new files in that folder and then also copies some user-specified files into it, and then finally copies the full contents of my temp folder into a user-specified final location. Everything works perfectly the first time you run this export process after launching the app, but crashes with an EXC_BAD_ACCESS error if it gets run more than once. The application-generated files are always created and written fine, but the crash always occurs when the FileManager attempts to copy one of the existing user-selected files, even though it passes my guard statements checking that the existing file is readable and the destination path is writable. If you re-launch the app, it will again run the first time no problem, but crashes the second.

Here is the relevant code:

let fm = FileManager.default
guard let existingINIURL = currentExportProfile!.existingINIFileURL else {
    return (false, "No INI file location provided.")
}

guard fm.fileExists(atPath: existingINIURL.path), fm.isReadableFile(atPath: existingINIURL.path) else {
    return (false, "Could not find INI file at specified path: \(existingINIURL.path) or path is not readable.")
}

guard let outputURL = exportTempFilesURL?.appendingPathComponent("OUTPUT", isDirectory: true), fm.fileExists(atPath: outputURL.path) else {
    return (false, "Problem accessing temp staging path")
}

guard fm.isReadableFile(atPath: existingINIURL.path) else {
    return (false, "Existing file is not readable")
}

guard fm.isWritableFile(atPath: outputURL.path) else {
    return (false, "Destination \(outputURL.path) is not writable")
}

do {
    try fm.copyItem(at: existingINIURL, to: outputURL.appendingPathComponent("CONTROL.INI"))
    return (true, nil)
} catch let error as NSError {
    Swift.print("Failed to copy existing INI with error: \(error)")
    return (false, "Failed to copy existing INI file with error: \(error)")
}

The EXC_BAD_ACCESS crash always occurs at the line:

try fm.copyItem(at: existingINIURL, to: outputURL.appendingPathComponent("CONTROL.INI"))

And since it's an access error of course it never reaches the catch statement to give me any indication of what the problem was.

Interesting note: Instead of copying with .appendingPathComponent("CONTROL.INI"), I tried copying the file with its current name and then renaming the copied file in a separate step. When I did this it seemed to be working at first, but it actually only made it so that it worked maybe 3-4 times before crashing the same way instead of always crashing on the second attempt with the same error, still at the fm.copyItem line.

Has anyone encountered any similar issues with FileManager?

Thanks!

Upvotes: 0

Views: 783

Answers (1)

DrRocket
DrRocket

Reputation: 235

I figured it out. It was because I forget I had set a delegate on the default FileManager at one point that no longer existed after the first cycle. After I changed the function that needed a delegate to use its own FileManager instance the problem went away.

Upvotes: 1

Related Questions