Problème avec les bindings et la libération d'objet
7 réponses
testuz73
Bonjour,
En ce moment j'essaie d'utiliser avec Cocoa les bindings introduit avec
Panther. Mais j'ai un problème avec la libération des objets.
Mon application est de la forme avec document. Ma sous-classe de
NSDocument à une fenêtre avec un bouton (Connecter). Lorsque je clique,
je crée un objet (base) qui se connecte à une base MySQL, puis je charge
un .nib avec une sous-classe de NSWindowController (qui a une variable
base qui pointe sur la base du document) et une fenêtre.
Quand je reclique (Déconnecter) sur le bouton, je libère le 2e
windowController et l'objet base.
Jusque là je n'ai aucun problème, lorsque je contrôle avec ObjectAlloc,
le 2e windowController et la base sont bien libéré.
Par contre, lorsque je rajoute un NSArrayController dans le 2e .nib et
lie sont contentArray avec la variable base.albums (un NSArray de base),
plus aucun objet n'est libéré lorsque je déconnecte la base.
Je précise que si le NSArrayController est dans le .nib, mais qu'il n'y
a pas de liaison avec base.albums les objets sont libérés correctement.
Je pense donc que la liaison empêche la bonne libération. Savez-vous
comment résoudre ce problème ? Merci
Merci pour les conseils, pas le temps maintenant mais je m'y mettrais.
Bon, je suis allez voir les 3 messages de ton dernier lien. C'est en effet exactement le problème. Il semble bien que ce soit un bug des bindings uniquement lorsqu'un NSWindowController est le propriétaire d'un nib et qu'il est lié. Bref, il y a bien un moyen de contourner ça mais c'est quand même tordu.
Merci pour les conseils, pas le temps maintenant mais je m'y mettrais.
Bon, je suis allez voir les 3 messages de ton dernier lien. C'est en
effet exactement le problème. Il semble bien que ce soit un bug des
bindings uniquement lorsqu'un NSWindowController est le propriétaire
d'un nib et qu'il est lié. Bref, il y a bien un moyen de contourner ça
mais c'est quand même tordu.
Merci pour les conseils, pas le temps maintenant mais je m'y mettrais.
Bon, je suis allez voir les 3 messages de ton dernier lien. C'est en effet exactement le problème. Il semble bien que ce soit un bug des bindings uniquement lorsqu'un NSWindowController est le propriétaire d'un nib et qu'il est lié. Bref, il y a bien un moyen de contourner ça mais c'est quand même tordu.
-- Frédéric Testuz <mailto:
Schmurtz
Frédéric Testuz wrote:
Bon, je suis allez voir les 3 messages de ton dernier lien. C'est en effet exactement le problème. Il semble bien que ce soit un bug des bindings uniquement lorsqu'un NSWindowController est le propriétaire d'un nib et qu'il est lié. Bref, il y a bien un moyen de contourner ça mais c'est quand même tordu.
Merci de me faire, un résumé des messages des archives. C'est un problème qui m'intéresse puisque je découvre aussi les bindings. Comme j'avais la flemme de lire les 3 messages en question, je t'ai donner le lien en espérant que ça puisse répondre et surtout de te montrer qu'on pouvait faire de recherches.
Tu t'es peut-être demandé pourquoi il demande une authentification et te donne le login/mdp. Après moulte réflexion, je pense que ça doit être pour arrêter les robots de recherche d'email des spammeurs.
-- Schmurtz
Frédéric Testuz wrote:
Bon, je suis allez voir les 3 messages de ton dernier lien. C'est en
effet exactement le problème. Il semble bien que ce soit un bug des
bindings uniquement lorsqu'un NSWindowController est le propriétaire
d'un nib et qu'il est lié. Bref, il y a bien un moyen de contourner ça
mais c'est quand même tordu.
Merci de me faire, un résumé des messages des archives. C'est un
problème qui m'intéresse puisque je découvre aussi les bindings. Comme
j'avais la flemme de lire les 3 messages en question, je t'ai donner le
lien en espérant que ça puisse répondre et surtout de te montrer qu'on
pouvait faire de recherches.
Tu t'es peut-être demandé pourquoi il demande une authentification et te
donne le login/mdp. Après moulte réflexion, je pense que ça doit être
pour arrêter les robots de recherche d'email des spammeurs.
Bon, je suis allez voir les 3 messages de ton dernier lien. C'est en effet exactement le problème. Il semble bien que ce soit un bug des bindings uniquement lorsqu'un NSWindowController est le propriétaire d'un nib et qu'il est lié. Bref, il y a bien un moyen de contourner ça mais c'est quand même tordu.
Merci de me faire, un résumé des messages des archives. C'est un problème qui m'intéresse puisque je découvre aussi les bindings. Comme j'avais la flemme de lire les 3 messages en question, je t'ai donner le lien en espérant que ça puisse répondre et surtout de te montrer qu'on pouvait faire de recherches.
Tu t'es peut-être demandé pourquoi il demande une authentification et te donne le login/mdp. Après moulte réflexion, je pense que ça doit être pour arrêter les robots de recherche d'email des spammeurs.
-- Schmurtz
testuz73
Schmurtz wrote:
Frédéric Testuz wrote:
Bon, je suis allez voir les 3 messages de ton dernier lien. C'est en effet exactement le problème. Il semble bien que ce soit un bug des bindings uniquement lorsqu'un NSWindowController est le propriétaire d'un nib et qu'il est lié. Bref, il y a bien un moyen de contourner ça mais c'est quand même tordu.
Merci de me faire, un résumé des messages des archives. C'est un problème qui m'intéresse puisque je découvre aussi les bindings. Comme j'avais la flemme de lire les 3 messages en question, je t'ai donner le lien en espérant que ça puisse répondre et surtout de te montrer qu'on pouvait faire de recherches.
En gros, ils supposent que le problème vient de ce que les bindings des views doivent être gérer par le windowController et qu'ils sont sans doute défaits lors du dealloc. Cependant le windowController semble être retenu (retain) par les bindings et par le nib donc le windowController n'est plus libéré lorsqu'il est fermé (un retain de trop) et qu'il est le propriétaire du nib.
La solution proposé est d'envoyé un unbind: à toutes les views qui sont liées dans windowWillClose: (le windowController doit être le delegate de la fenêtre).
Je colle le message de la liste en-dessous, il résume le tout avec une explication de ses essais.
Tu t'es peut-être demandé pourquoi il demande une authentification et te donne le login/mdp. Après moulte réflexion, je pense que ça doit être pour arrêter les robots de recherche d'email des spammeurs.
Pour le mot de passe, c'est indiqué sur la page de résultat. C'est bien contre les spammeurs et le user:pass est indiqué sur la page : archives:archives.
***** OK, this is a update to this thread to let everybody know how this turned out (I wouldn't want anybody looking for info on this problem to see this and think everything is resolved, because it isn't).
First of all, I'll point out that Allen Odgaard was right about the "windowWillClose" notification or delegate method being the proper place to put this "setWindow: with nil". I tried putting it in the window controller -close method, but there is no guarantee it will be called.
Also, it does do what is intended: it releases the window controller's "retain" on the window.
I was so sure this would solve my binding/memory leak problems that I installed it directly into my real application rather than trying it first in one of my tiny test applications. The window controller still hung around after I closed the window, though, so I went back to my test code to see what was going on.
This test application is minimally modified from the cocoa document-based project that is generated when you create a new project in Xcode. This application has one custom window controller class, the window controller is the File's Owner of a nib file with one window that contains a single NSTextField control, and the text view has a binding to a variable that is accessed with a path through the window controller. When the window is closed, the window controller and window are not released, even though when I have a similar setup with the document as the File's Owner, everything _is_ released.
So, I rebuilt the application after adding the following method to the window controller subclass:
I ran it under ObjectAlloc and determined that the window controller still doesn't go away when the window is closed. I decided to take a look at the retain/release call sequence of the NSWindow to determine why it did not get released, but I couldn'f find it. It _had been released. The [self setWindow:nil]; statement did what was intended.
Hmmm.
I had already determined from looking at the retain/release sequence for the window controller that it was almost certainly the retain from the binding that wasn't being balanced with a release. I went looking for the NSTextField object that had the binding.
ObjectAlloc said the NSTextField had also been released. But the NSTextFieldCell object was still there.
At this point the theme music from "Twilight Zone" started playing in my head. OK, why was this guy hanging around?
Turns out it was retained by the binding also.
It looks like the only way the retain cycle can be broken is, as Allen suggested in a previous message, to send an unbind message to each view object that has a binding. The question presents itself, why do things work (as I outlined in a previous message) when the window controller object is not the File's Owner, but you get memory leaks when it is the File's Owner?
My theory at this point is that the window controller is the object that is responsible for keeping track of the bindings and issuing unbind commands to the view objects, but it can't do this when it is itself a target of bindings (perhaps the unbind messages are issued in the dealloc method).
Or maybe the truth is more complicated than that. It probably is, but as it is all a black box to me, I think I've gone as far as I can in trying to work around this problem. I have to get on with development. I will definitely file a bug with Apple, though -- it's pretty clear something needs to be fixed.
- Dennis D.
-- Frédéric Testuz <mailto:
Schmurtz <moi@ici.com> wrote:
Frédéric Testuz wrote:
Bon, je suis allez voir les 3 messages de ton dernier lien. C'est en
effet exactement le problème. Il semble bien que ce soit un bug des
bindings uniquement lorsqu'un NSWindowController est le propriétaire
d'un nib et qu'il est lié. Bref, il y a bien un moyen de contourner ça
mais c'est quand même tordu.
Merci de me faire, un résumé des messages des archives. C'est un
problème qui m'intéresse puisque je découvre aussi les bindings. Comme
j'avais la flemme de lire les 3 messages en question, je t'ai donner le
lien en espérant que ça puisse répondre et surtout de te montrer qu'on
pouvait faire de recherches.
En gros, ils supposent que le problème vient de ce que les bindings des
views doivent être gérer par le windowController et qu'ils sont sans
doute défaits lors du dealloc. Cependant le windowController semble être
retenu (retain) par les bindings et par le nib donc le windowController
n'est plus libéré lorsqu'il est fermé (un retain de trop) et qu'il est
le propriétaire du nib.
La solution proposé est d'envoyé un unbind: à toutes les views qui sont
liées dans windowWillClose: (le windowController doit être le delegate
de la fenêtre).
Je colle le message de la liste en-dessous, il résume le tout avec une
explication de ses essais.
Tu t'es peut-être demandé pourquoi il demande une authentification et te
donne le login/mdp. Après moulte réflexion, je pense que ça doit être
pour arrêter les robots de recherche d'email des spammeurs.
Pour le mot de passe, c'est indiqué sur la page de résultat. C'est bien
contre les spammeurs et le user:pass est indiqué sur la page :
archives:archives.
*****
OK, this is a update to this thread to let everybody know how this
turned out (I wouldn't want anybody looking for info on this problem to
see this and think everything is resolved, because it isn't).
First of all, I'll point out that Allen Odgaard was right about the
"windowWillClose" notification or delegate method being the proper
place to put this "setWindow: with nil". I tried putting it in the
window controller -close method, but there is no guarantee it will be
called.
Also, it does do what is intended: it releases the window controller's
"retain" on the window.
I was so sure this would solve my binding/memory leak problems that I
installed it directly into my real application rather than trying it
first in one of my tiny test applications. The window controller still
hung around after I closed the window, though, so I went back to my
test code to see what was going on.
This test application is minimally modified from the cocoa
document-based project that is generated when you create a new project
in Xcode. This application has one custom window controller class, the
window controller is the File's Owner of a nib file with one window
that contains a single NSTextField control, and the text view has a
binding to a variable that is accessed with a path through the window
controller. When the window is closed, the window controller and window
are not released, even though when I have a similar setup with the
document as the File's Owner, everything _is_ released.
So, I rebuilt the application after adding the following method to the
window controller subclass:
I ran it under ObjectAlloc and determined that the window controller
still doesn't go away when the window is closed. I decided to take a
look at the retain/release call sequence of the NSWindow to determine
why it did not get released, but I couldn'f find it. It _had been
released. The [self setWindow:nil]; statement did what was intended.
Hmmm.
I had already determined from looking at the retain/release sequence
for the window controller that it was almost certainly the retain from
the binding that wasn't being balanced with a release. I went looking
for the NSTextField object that had the binding.
ObjectAlloc said the NSTextField had also been released. But the
NSTextFieldCell object was still there.
At this point the theme music from "Twilight Zone" started playing in
my head. OK, why was this guy hanging around?
Turns out it was retained by the binding also.
It looks like the only way the retain cycle can be broken is, as Allen
suggested in a previous message, to send an unbind message to each view
object that has a binding. The question presents itself, why do things
work (as I outlined in a previous message) when the window controller
object is not the File's Owner, but you get memory leaks when it is the
File's Owner?
My theory at this point is that the window controller is the object
that is responsible for keeping track of the bindings and issuing
unbind commands to the view objects, but it can't do this when it is
itself a target of bindings (perhaps the unbind messages are issued in
the dealloc method).
Or maybe the truth is more complicated than that. It probably is, but
as it is all a black box to me, I think I've gone as far as I can in
trying to work around this problem. I have to get on with development.
I will definitely file a bug with Apple, though -- it's pretty clear
something needs to be fixed.
Bon, je suis allez voir les 3 messages de ton dernier lien. C'est en effet exactement le problème. Il semble bien que ce soit un bug des bindings uniquement lorsqu'un NSWindowController est le propriétaire d'un nib et qu'il est lié. Bref, il y a bien un moyen de contourner ça mais c'est quand même tordu.
Merci de me faire, un résumé des messages des archives. C'est un problème qui m'intéresse puisque je découvre aussi les bindings. Comme j'avais la flemme de lire les 3 messages en question, je t'ai donner le lien en espérant que ça puisse répondre et surtout de te montrer qu'on pouvait faire de recherches.
En gros, ils supposent que le problème vient de ce que les bindings des views doivent être gérer par le windowController et qu'ils sont sans doute défaits lors du dealloc. Cependant le windowController semble être retenu (retain) par les bindings et par le nib donc le windowController n'est plus libéré lorsqu'il est fermé (un retain de trop) et qu'il est le propriétaire du nib.
La solution proposé est d'envoyé un unbind: à toutes les views qui sont liées dans windowWillClose: (le windowController doit être le delegate de la fenêtre).
Je colle le message de la liste en-dessous, il résume le tout avec une explication de ses essais.
Tu t'es peut-être demandé pourquoi il demande une authentification et te donne le login/mdp. Après moulte réflexion, je pense que ça doit être pour arrêter les robots de recherche d'email des spammeurs.
Pour le mot de passe, c'est indiqué sur la page de résultat. C'est bien contre les spammeurs et le user:pass est indiqué sur la page : archives:archives.
***** OK, this is a update to this thread to let everybody know how this turned out (I wouldn't want anybody looking for info on this problem to see this and think everything is resolved, because it isn't).
First of all, I'll point out that Allen Odgaard was right about the "windowWillClose" notification or delegate method being the proper place to put this "setWindow: with nil". I tried putting it in the window controller -close method, but there is no guarantee it will be called.
Also, it does do what is intended: it releases the window controller's "retain" on the window.
I was so sure this would solve my binding/memory leak problems that I installed it directly into my real application rather than trying it first in one of my tiny test applications. The window controller still hung around after I closed the window, though, so I went back to my test code to see what was going on.
This test application is minimally modified from the cocoa document-based project that is generated when you create a new project in Xcode. This application has one custom window controller class, the window controller is the File's Owner of a nib file with one window that contains a single NSTextField control, and the text view has a binding to a variable that is accessed with a path through the window controller. When the window is closed, the window controller and window are not released, even though when I have a similar setup with the document as the File's Owner, everything _is_ released.
So, I rebuilt the application after adding the following method to the window controller subclass:
I ran it under ObjectAlloc and determined that the window controller still doesn't go away when the window is closed. I decided to take a look at the retain/release call sequence of the NSWindow to determine why it did not get released, but I couldn'f find it. It _had been released. The [self setWindow:nil]; statement did what was intended.
Hmmm.
I had already determined from looking at the retain/release sequence for the window controller that it was almost certainly the retain from the binding that wasn't being balanced with a release. I went looking for the NSTextField object that had the binding.
ObjectAlloc said the NSTextField had also been released. But the NSTextFieldCell object was still there.
At this point the theme music from "Twilight Zone" started playing in my head. OK, why was this guy hanging around?
Turns out it was retained by the binding also.
It looks like the only way the retain cycle can be broken is, as Allen suggested in a previous message, to send an unbind message to each view object that has a binding. The question presents itself, why do things work (as I outlined in a previous message) when the window controller object is not the File's Owner, but you get memory leaks when it is the File's Owner?
My theory at this point is that the window controller is the object that is responsible for keeping track of the bindings and issuing unbind commands to the view objects, but it can't do this when it is itself a target of bindings (perhaps the unbind messages are issued in the dealloc method).
Or maybe the truth is more complicated than that. It probably is, but as it is all a black box to me, I think I've gone as far as I can in trying to work around this problem. I have to get on with development. I will definitely file a bug with Apple, though -- it's pretty clear something needs to be fixed.
- Dennis D.
-- Frédéric Testuz <mailto:
testuz73
Frédéric Testuz wrote:
La solution proposé est d'envoyé un unbind: à toutes les views qui sont liées dans windowWillClose: (le windowController doit être le delegate de la fenêtre).
Je précise : dans mon cas, il fallait faire un unbind: sur le NSArrayController. J'en déduis qu'il faut délier les objets qui sont lié au NSWindowController uniquement (lorsqu'il est Nib's owner). Chez moi, les views étaient liées à l'arrayController et pas au windowController.
La solution proposé est d'envoyé un unbind: à toutes les views qui sont
liées dans windowWillClose: (le windowController doit être le delegate
de la fenêtre).
Je précise : dans mon cas, il fallait faire un unbind: sur le
NSArrayController.
J'en déduis qu'il faut délier les objets qui sont lié au
NSWindowController uniquement (lorsqu'il est Nib's owner). Chez moi, les
views étaient liées à l'arrayController et pas au windowController.
La solution proposé est d'envoyé un unbind: à toutes les views qui sont liées dans windowWillClose: (le windowController doit être le delegate de la fenêtre).
Je précise : dans mon cas, il fallait faire un unbind: sur le NSArrayController. J'en déduis qu'il faut délier les objets qui sont lié au NSWindowController uniquement (lorsqu'il est Nib's owner). Chez moi, les views étaient liées à l'arrayController et pas au windowController.
-- Frédéric Testuz <mailto:
Schmurtz
Bon, je suis allez voir les 3 messages de ton dernier lien. C'est en effet exactement le problème. Il semble bien que ce soit un bug des bindings uniquement lorsqu'un NSWindowController est le propriétaire d'un nib et qu'il est lié. Bref, il y a bien un moyen de contourner ça mais c'est quand même tordu.
Merci de me faire un résumé des messages des archives.
C'était pour te remercier d'avoir fait un vague résumé, pas pour demander un résumé :)
Je me suis peut-être un peu mal exprimé
Je poste ce message juste pour ne pas avoir l'air de quelqu'un qui fait faire des résumés par les autres des archives qu'il a pas envi de lire :)
Merci quand même
-- Schmurtz
Bon, je suis allez voir les 3 messages de ton dernier lien. C'est en
effet exactement le problème. Il semble bien que ce soit un bug des
bindings uniquement lorsqu'un NSWindowController est le propriétaire
d'un nib et qu'il est lié. Bref, il y a bien un moyen de contourner ça
mais c'est quand même tordu.
Merci de me faire un résumé des messages des archives.
C'était pour te remercier d'avoir fait un vague résumé, pas pour
demander un résumé :)
Je me suis peut-être un peu mal exprimé
Je poste ce message juste pour ne pas avoir l'air de quelqu'un qui fait
faire des résumés par les autres des archives qu'il a pas envi de lire :)
Bon, je suis allez voir les 3 messages de ton dernier lien. C'est en effet exactement le problème. Il semble bien que ce soit un bug des bindings uniquement lorsqu'un NSWindowController est le propriétaire d'un nib et qu'il est lié. Bref, il y a bien un moyen de contourner ça mais c'est quand même tordu.
Merci de me faire un résumé des messages des archives.
C'était pour te remercier d'avoir fait un vague résumé, pas pour demander un résumé :)
Je me suis peut-être un peu mal exprimé
Je poste ce message juste pour ne pas avoir l'air de quelqu'un qui fait faire des résumés par les autres des archives qu'il a pas envi de lire :)