Pb d'accès au NSNotificationCenter

SukabusSukabus Membre
06:56 modifié dans API AppKit #1
Bonjour à  tous,

Je suis tout nouveau sous Cocoa et j'ai un problème concernant les Notifications.
J'ai un objet de classe MapDocument (dérivant de NSDocument) que je souhaite enregistrer auprès du centre de notification.
Dans la méthode init de la classe je fait ceci :
<br />- (id)init<br />{<br />	if (![super init])<br />		return nil;<br /><br />	NSNotificationCenter *notifCenter = [NSNotificationCenter defaultCenter]; <br />	[notifCenter addObserver:self selector:@selector(handleLocationChange:) name:LocationChangedNotification object:nil];<br />	return self;<br />}<br />


Le problème est que lorsque j'appelle addObserver sur notifCenter j'obtient un magnifique EXC_BAD_ACCESS.
J'ai vérifié avec le debugger que notifCenter a été bien alloué et n'est pas à  nil.
si je remplace l'appel à  addObserver par
<br />NSLog (@&quot;Centre de notification courant : %@&quot;, notifCenter;<br />

Même chose : EXC_BAD_ACCESS

Dans une autre fonction de l'application, je souhaite poster une notification :
<br />	NSNotificationCenter *notifCenter = [NSNotificationCenter defaultCenter];<br />	NSDictionary *notifInfos = [NSDictionary dictionaryWithObject:newLocationBoundingBox forKey:@&quot;LocationBoundingBox&quot;];<br />	[notifCenter postNotificationName:LocationChangedNotification object:self userInfo:notifInfos];<br />

Et là  même erreur : EXC_BAD_ACCESS quand je fait appel à  postNotificationName:object:userInfo:

En fait, dès que j'essaie d'utiliser ou d'accéder au centre de notification, j'obtient cette erreur.
Il y a certainement quelque chose que je n'ai pas compris, mais très honnêtement je ne vois pas.

Merci pour votre aide.

Réponses

  • Philippe49Philippe49 Membre
    janvier 2009 modifié #2
    Bienvenu sur le site Sukabus !

    La clé LocationChangedNotification est bien définie en global (ou visible depuis le fichier appelant)?
    Ta classe possède-t-elle une méthode de signature
    -(void) handleLocationChange:(NSNotification *) notification ;

    dans 1231294566:

    J'ai vérifié avec le debugger que notifCenter a été bien alloué et n'est pas à  nil.
    si je remplace l'appel à  addObserver par
    <br />NSLog (@&quot;Centre de notification courant : %@&quot;, notifCenter;<br />
    

    Même chose : EXC_BAD_ACCESS


    Il semble y avoir une contradiction entre ces deux phrases ...

  • MalaMala Membre, Modérateur
    06:56 modifié #3
    dans 1231294566:

    En fait, dès que j'essaie d'utiliser ou d'accéder au centre de notification, j'obtient cette erreur.
    Il y a certainement quelque chose que je n'ai pas compris, mais très honnêtement je ne vois pas.

    Merci pour votre aide.


    Si je fais un :
    <br />NSNotificationCenter *notifCenter = [NSNotificationCenter defaultCenter]; <br />NSLog (@&quot;Centre de notification courant : %@&quot;, notifCenter);<br />
    


    Tout est ok chez moi. J'aurais plutôt tendance à  pencher pour une violation d'accès ailleurs dans le code qui aurait pour effet de corrompre le centre de notification.

    Ton code s'exécute dans le thread principal de l'appli?



  • Philippe49Philippe49 Membre
    06:56 modifié #4
    Doc : Notification Programming Topics For Cocoa

    In a multithreaded application, notifications are always delivered in the thread in which the notification was posted, which may not be the same thread in which an observer registered itself.
  • MalaMala Membre, Modérateur
    06:56 modifié #5
    dans 1231319354:

    Doc : Notification Programming Topics For Cocoa

    In a multithreaded application, notifications are always delivered in the thread in which the notification was posted, which may not be the same thread in which an observer registered itself.

    Merci Phil. Donc pas de problème possible de ce côté là .

    Le problème avec un EXC_BAD_ACCESS c'est que c'est par forcément là  où ça plante que se trouve le bug.
  • Philippe49Philippe49 Membre
    06:56 modifié #6
    Oui, et puis avec un mélange thread / notification, l'embrouille n'est pas loin.
  • SukabusSukabus Membre
    06:56 modifié #7
    Bonjour,

    Je viens de reprendre mon code (Marseille + Neige = c'est la panique totale :o ).
    Alors :
    - La clé LocationChangedNotification est bien globale et visible
    - handleLocationChange: existe et fait partie de la classe MapDocument
    - Mon application est mono thread. J'ai bien vu que dans la doc NSNotificationCenter devait etre utilisé dans le même thread, sinon il faut utiliser NSDistributedNotificationCenter (si j'ai bien compris).

    En fait l'erreur (car je l'ai trouvée) était vraiment toute bête : lors de la déclaration de LocationChangedNotification suivante
    <br />NSString * const LocationChangedNotification = &quot;LocationChangedNotification&quot;;<br />
    

    il y a une erreur de débutant en Objective-C : il manque un .
    Il faudra bien que ca me rentre un jour dans la tête cette histoire d'arobase  :crackboom:- et que je soit plus attentif au Warning (honte à  moi).

    Merci tout de même pour votre aide.
  • Philippe49Philippe49 Membre
    06:56 modifié #8
    Oui, le EXC_BAD_ACCESS dû à  @ c'est un grand classique , du à  la différence entre un objet NSString et à  une chaà®ne de caractères C classique.

    Pour les threads, NSNotificationCenter peut-être utilisé dans des threads différents, bien que cela soit à  régler aux petits oignons. Penser à  utiliser en priorité des méthodes comme performSelectorOnMainThread... est une bonne idée dans ce genre de configuration..
    NSDistributionNotificationCenter agit entre les différentes tâches d'une machine.


    NSNotificationCenter

    Each task has a default notification center that you access with the NSNotificationCenter +defaultCenter method. This notification center handles notifications within a single task. For communication between tasks on the same machine, use a distributed notification center (see “NSDistributedNotificationCenter”).

    A notification center delivers notifications to observers synchronously. In other words, when posting a notification, control does not return to the poster until all observers have received and processed the notification. To send notifications asynchronously use a notification queue, which is described in “Notification Queues.”

    In a multithreaded application, notifications are always delivered in the thread in which the notification was posted, which may not be the same thread in which an observer registered itself.
Connectez-vous ou Inscrivez-vous pour répondre.