NSDocument never deallocated with autosave/versions

  • I've got a large memory leak in my app because my document class is never deallocated once I've added content to it.

    I've been over it with a fine-toothed comb and I'm prepared to say it doesn't look as if I'm doing anything wrong. I overrode -retain and set a breakpoint there, so I could see who is retaining the document. Of course, many, many objects do in the complicated new world of autosaving, versions and blocks.

    Every single retain on NSDocument comes from the internals of Cocoa - my code never retains the document at all.

    The key object that seems never to release my document is the NSSavePanel that is displayed only when I have added content, and I close the window. The save panel is shown, and the retain count shoots right up. If I click 'Don't Save', the window closes as expected but the document is still retained - the retain count does not go back down to the point it was at prior to the dialog showing up, and dealloc is never called.

    Key point: If I disable autosaving for my document class, the document is deallocated as expected.

    What I want to know is, is this behaviour correct? It doesn't seem to be correct but it could be - perhaps Versions is retaining my document after its normal lifetime for its own purposes? Obviously I understand that peeking retain counts is a bad strategy for debugging, but just looking at the general trend here, the document ticks over at about a retain count of 3 or 4. When the save dialog is presented, it can shoot up to 17-20 counts, and on closure this drops back to about 12. With autosave/versions disabled, it goes to zero.

    If Versions is retaining documents for some reason, fair enough, I guess I have to accept it. But it causes awkward bugs because of the clean up I expect to do in -dealloc, like unsubscribing from notifications and so on. I'm also a bit uneasy about having large objects like this which are heavily customised in my app hanging around because Cocoa thinks it knows what to do with them - surely it can't know how a particular class has been subclassed and always do the right thing? The way Versions works seems really quite scary to me.

    --Graham
  • Well well.

    This leak only occurs if I have sandboxing enabled. What a surprise!

    The save dialog is not releasing the document when it closes if sandboxing is turned on. If I repeatedly close the window but cancel the save dialog, the retain count goes up by about 9 counts each time.

    Sandboxing is simply not ready for prime time, and I feel very frustrated that it is now compulsory for the App Store when it is this broken.

    --Graham

    On 30/05/2012, at 12:05 PM, Graham Cox wrote:

    > I've got a large memory leak in my app because my document class is never deallocated once I've added content to it.
    >
    > I've been over it with a fine-toothed comb and I'm prepared to say it doesn't look as if I'm doing anything wrong. I overrode -retain and set a breakpoint there, so I could see who is retaining the document. Of course, many, many objects do in the complicated new world of autosaving, versions and blocks.
    >
    > Every single retain on NSDocument comes from the internals of Cocoa - my code never retains the document at all.
    >
    > The key object that seems never to release my document is the NSSavePanel that is displayed only when I have added content, and I close the window. The save panel is shown, and the retain count shoots right up. If I click 'Don't Save', the window closes as expected but the document is still retained - the retain count does not go back down to the point it was at prior to the dialog showing up, and dealloc is never called.
    >
    > Key point: If I disable autosaving for my document class, the document is deallocated as expected.
    >
    > What I want to know is, is this behaviour correct? It doesn't seem to be correct but it could be - perhaps Versions is retaining my document after its normal lifetime for its own purposes? Obviously I understand that peeking retain counts is a bad strategy for debugging, but just looking at the general trend here, the document ticks over at about a retain count of 3 or 4. When the save dialog is presented, it can shoot up to 17-20 counts, and on closure this drops back to about 12. With autosave/versions disabled, it goes to zero.
    >
    > If Versions is retaining documents for some reason, fair enough, I guess I have to accept it. But it causes awkward bugs because of the clean up I expect to do in -dealloc, like unsubscribing from notifications and so on. I'm also a bit uneasy about having large objects like this which are heavily customised in my app hanging around because Cocoa thinks it knows what to do with them - surely it can't know how a particular class has been subclassed and always do the right thing? The way Versions works seems really quite scary to me.
  • I guess you should implement -[NSDocument close] to do your cleanup then.

    On 30 May 2012, at 04:30, Graham Cox wrote:

    > Well well.
    >
    > This leak only occurs if I have sandboxing enabled. What a surprise!
    >
    > The save dialog is not releasing the document when it closes if sandboxing is turned on. If I repeatedly close the window but cancel the save dialog, the retain count goes up by about 9 counts each time.
    >
    > Sandboxing is simply not ready for prime time, and I feel very frustrated that it is now compulsory for the App Store when it is this broken.
    >
    > --Graham
    >
    >
    >
    >
    >
    >
    >
    > On 30/05/2012, at 12:05 PM, Graham Cox wrote:
    >
    >> I've got a large memory leak in my app because my document class is never deallocated once I've added content to it.
    >>
    >> I've been over it with a fine-toothed comb and I'm prepared to say it doesn't look as if I'm doing anything wrong. I overrode -retain and set a breakpoint there, so I could see who is retaining the document. Of course, many, many objects do in the complicated new world of autosaving, versions and blocks.
    >>
    >> Every single retain on NSDocument comes from the internals of Cocoa - my code never retains the document at all.
    >>
    >> The key object that seems never to release my document is the NSSavePanel that is displayed only when I have added content, and I close the window. The save panel is shown, and the retain count shoots right up. If I click 'Don't Save', the window closes as expected but the document is still retained - the retain count does not go back down to the point it was at prior to the dialog showing up, and dealloc is never called.
    >>
    >> Key point: If I disable autosaving for my document class, the document is deallocated as expected.
    >>
    >> What I want to know is, is this behaviour correct? It doesn't seem to be correct but it could be - perhaps Versions is retaining my document after its normal lifetime for its own purposes? Obviously I understand that peeking retain counts is a bad strategy for debugging, but just looking at the general trend here, the document ticks over at about a retain count of 3 or 4. When the save dialog is presented, it can shoot up to 17-20 counts, and on closure this drops back to about 12. With autosave/versions disabled, it goes to zero.
    >>
    >> If Versions is retaining documents for some reason, fair enough, I guess I have to accept it. But it causes awkward bugs because of the clean up I expect to do in -dealloc, like unsubscribing from notifications and so on. I'm also a bit uneasy about having large objects like this which are heavily customised in my app hanging around because Cocoa thinks it knows what to do with them - surely it can't know how a particular class has been subclassed and always do the right thing? The way Versions works seems really quite scary to me.

  • On May 29, 2012, at 10:05 PM, Graham Cox <graham.cox...> wrote:

    > The key object that seems never to release my document is the NSSavePanel that is displayed only when I have added content, and I close the window. The save panel is shown, and the retain count shoots right up. If I click 'Don't Save', the window closes as expected but the document is still retained - the retain count does not go back down to the point it was at prior to the dialog showing up, and dealloc is never called.
    >
    > Key point: If I disable autosaving for my document class, the document is deallocated as expected.

    Do you override any of the saving methods and fail to call their completion handlers in the Don't Save case?

    --Kyle Sluder
  • On 30/05/2012, at 8:55 PM, Kyle Sluder wrote:

    >> Key point: If I disable autosaving for my document class, the document is deallocated as expected.
    >
    > Do you override any of the saving methods and fail to call their completion handlers in the Don't Save case?

    No; I only override the fileWrapper... and readFileWrapper... methods. I'm not doing anything tricky with the standard flow control of save/dont save/cancel.

    I'm going to put together a clean simple NSDocument-based test case to check that the bug can be reproduced in that case.

    > I guess you should implement -[NSDocument close] to do your cleanup then.

    Indeed, I have done. But that doesn't fix the bug, it only mitigates its effects. A leak is still there, and it's a potentially quite large one, since NSDocument owns my data model.

    --Graham
  • On May 30, 2012, at 8:13 AM, Graham Cox <graham.cox...> wrote:

    >
    >> I guess you should implement -[NSDocument close] to do your cleanup then.
    >
    > Indeed, I have done. But that doesn't fix the bug, it only mitigates its effects. A leak is still there, and it's a potentially quite large one, since NSDocument owns my data model.

    Surely you can invalidate your data model within -close? How does NSDocument otherwise have a handle on it?

    --Kyle Sluder
  • On 30/05/2012, at 10:19 PM, Kyle Sluder wrote:

    > Surely you can invalidate your data model within -close? How does NSDocument otherwise have a handle on it?

    Of course I can, but that surely isn't the point. Are leaks somehow OK now?

    --Graham
  • On May 30, 2012, at 7:40 AM, Graham Cox <graham.cox...> wrote:

    >
    > On 30/05/2012, at 10:19 PM, Kyle Sluder wrote:
    >
    >> Surely you can invalidate your data model within -close? How does NSDocument otherwise have a handle on it?
    >
    >
    > Of course I can, but that surely isn't the point. Are leaks somehow OK now?

    No, but it sounded like you believed there was not a point at whch you could mitigate the effects of the leak.

    --Kyle Sluder
previous month may 2012 next month
MTWTFSS
  1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30 31      
Go to today