web-dev-qa-db-fra.com

Comment résoudre le 'sélecteur non reconnu envoyé à l'instance'?

Dans AppDelegate, j'alloue une instance définie dans une bibliothèque statique. Cette instance a une propriété NSString définie une "copie". Lorsque j'accède à la propriété de chaîne sur cette instance, l'application se bloque avec le «sélecteur non reconnu envoyé à l'instance». Xcode fournit un indice de code pour la propriété, ce qui signifie qu'elle est connue dans l'application appelante. La classe particulière est compilée dans la cible de la bibliothèque statique. Qu'est-ce que je rate?

Ajout de code.

//static library 
//ClassA.h
@interface ClassA : NSObject {
...
NSString *downloadUrl;
}
@property(nonatomic, copy) NSString *downloadUrl;

//ClassA.m
@synthesize downloadUrl;

Dans l'appDélégant de l'application appelante.

//app delegate header file
@interface myApp : NSObject <UIApplicationDelegate> {
ClassA *classA;
}
@property (nonatomic, retain) ClassA *classA;

//app delegate .m file
@synthesize classA;

- (void)applicationDidFinishLaunching:(UIApplication *)application {
classA = [[ClassA alloc] init];
//exception occurs here.  downloadUrl is of type NSCFNumber
classA.downloadUrl = @"http://www.abc.com/";
...}

Les autres classes de l'application obtiendront une référence au délégué et appelleront classA.downloadUrl.

36
4thSpace

1) Le synthétiseur est-il dans le bloc @implementation?

2) Devriez-vous vous référer à self.classA = [[ClassA alloc] init]; et self.classA.downloadUrl = @"..." au lieu de plain classA?

3) Dans votre fichier myApp.m, vous devez importer ClassA.h. Lorsqu'il est manquant, il s'agit par défaut d'un nombre ou d'un pointeur? (Dans C, les variables utilisent par défaut int si elles ne sont pas trouvées par le compilateur):

#import "ClassA.h".

26
stefanB

Définir l'indicateur -ObjC in Autre éditeur de liens Indicateur dans le paramètre de projet ... (pas dans le projet de bibliothèque statique, mais dans le projet que vous utilisez avec une bibliothèque statique ...). Toutes les configurations  

18
mihir mehta

Beaucoup de gens ont donné des réponses très techniques à cette question et à des questions similaires, mais je pense que c'est plus simple que cela. Parfois, si vous ne faites pas attention, un sélecteur que vous n'avez pas l'intention d'utiliser peut être attaché à quelque chose dans l'interface. Cette erreur est peut-être due à la présence du sélecteur, mais vous n'avez pas écrit de code pour cela. 

Le moyen le plus simple de vérifier que ce n'est pas le cas est de cliquer avec le bouton droit de la souris sur l'élément de manière à afficher tous les sélecteurs qui lui sont associés. S'il y a quelque chose que vous ne voulez pas être là-dedans, éliminez-le! J'espère que cela t'aides...

14
Dave Kanter

Le mien était quelque chose de simple/stupide. Erreur de débutant, pour toute personne ayant converti son NSManagedObject en un NSObject normal.

J'ai eu:

@dynamic order_id;

quand j'aurais dû avoir:

@synthesize order_id;
1
Dan Power

Comment importez-vous ClassA dans votre classe AppDelegate? Avez-vous inclus le fichier .h dans le projet principal? J'ai eu ce problème pendant un moment parce que je n'ai pas copié le fichier d'en-tête dans le projet principal, ainsi que le #include "ClassA.h" normal. 

Copier ou créer le fichier .h le résolut pour moi.

1
Heat Miser

Pour moi, la cause de cette erreur est que le même message a été envoyé deux fois au même membre du groupe. Lorsque j'ai cliqué avec le bouton droit de la souris sur le bouton de l'interface graphique, je pouvais voir le nom de la méthode deux fois et je venais d'en supprimer un. Erreur du débutant dans mon cas, bien sûr, mais je voulais le faire savoir aux autres débutants. 

1
Rich

Dans le code que vous avez posté, vous envoyez le setDownloadURL: setter à ClassA - c'est-à-dire la classe elle-même . Vous voulez définir la propriété d'une instance.

1
Chuck

Vous devriez noter que ce n'est pas nécessairement le meilleur modèle de conception. À première vue, vous utilisez essentiellement votre délégué d'application pour stocker ce qui équivaut à une variable globale.

Matt Gallagher a bien abordé la question des globals dans son article sur Cocoa with Love à http://cocoawithlove.com/2008/11/singletons-appdelegates-and-top-level.html . Selon toute vraisemblance, votre ClassA devrait être un singleton plutôt qu'un global dans AppDelegate, bien qu'il soit possible que vous vouliez que ClassA soit plus général et pas simplement un singleton. Dans ce cas, il serait probablement préférable d'utiliser une méthode de classe pour renvoyer une instance préconfigurée de la classe A, quelque chose comme:

+ (ClassA*) applicationClassA
{
    static ClassA* appClassA = nil;
    if ( !appClassA ) {
        appClassA = [[ClassA alloc] init];
        appClassA.downloadURL = @"http://www.abc.com/";
    }
    return appClassA;
}

Sinon, vous pouvez créer une nouvelle classe dont le seul objectif est de contenir cette méthode.

Le fait est que les éléments globaux d'application n'ont pas besoin de faire partie d'AppDelegate. Le fait que AppDelegate soit un singleton connu ne signifie pas que toutes les autres applications globales doivent y être associées, même si elles n’ont rien à voir avec la gestion des méthodes de délégation NSApplication.

0
Peter N Lewis

Très bizarre, mais. Vous devez déclarer la classe de votre instance d'application en tant que myApplication: UIApplication au lieu de myApplication: NSObject. Il semble que le protocole UIApplicationDelegate n'implémente pas le message + registerForSystemEvents. Crazy Apple APIs, encore.

0
H2CO3