34

In AppDelegate, sto allocando un'istanza definita in una libreria statica. Questa istanza ha una proprietà NSString imposta una "copia". Quando accedo alla proprietà stringa su questa istanza, l'app si arresta in modo anomalo con "selettore non riconosciuto inviato all'istanza". Xcode fornisce un suggerimento sul codice per la proprietà, il che significa che è noto nell'app chiamante. La classe particolare è compilata nel target della libreria statica. Cosa mi manca?Come risolvere "selettore non riconosciuto inviato all'istanza"?

Aggiunta di codice.

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

//ClassA.m 
@synthesize downloadUrl; 

Nel AppDelegate dell'app chiamata.

//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/"; 
...} 

Altre classi in applicazione otterrà un riferimento al delegato e chiamare classA.downloadUrl.

+2

penso che sarà necessario inserire frammenti di codice e il messaggio di errore completo di ottenere molto aiuto qui. – smorgan

risposta

25

1) Se l'sintetizzare entro @implementation blocco?

2) Si dovrebbe fare riferimento a self.classA = [[ClassA alloc] init]; e self.classA.downloadUrl = @"..." anziché normale classA?

3) Nel file myApp.m è necessario importare ClassA.h, quando manca manca un numero o un puntatore? (In variabili C di default a int se non viene trovato dal compilatore):

#import "ClassA.h".

+1

L'ho già provato. Ancora ottenere un'eccezione. Ho diverse altre classi simili nella stessa libreria. Nessuno di loro ha questo problema. – 4thSpace

+0

Hai provato [classA setDownloadUrl: @ "http://www.abc.com/"]; ....? – stefanB

+0

... Ovviamente il "www" è stato abbreviato in collegamento web nel commento precedente – stefanB

1

Nel codice che hai postato, si invia la setDownloadURL: setter a ClassA - vale a dire, la classe . Vuoi impostare la proprietà di un'istanza.

+0

Nella classe statica ho @property (nonatomic, copy) NSString * theString e theString è @synthesize. C'è qualcos'altro? – 4thSpace

+0

Mi accorgo che quando passo il mouse su theString sul lato del chiamante, il suo tipo è NSCFNumber. Dovrebbe essere NSString. – 4thSpace

+0

come si accede? – stefanB

1

Come stai importando ClasseA nella vostra classe AppDelegate? Hai inserito il file .h nel progetto principale? Ho avuto questo problema per un po 'perché non ho copiato il file di intestazione nel progetto principale così come il normale # include "ClassA.h."

copia, o la creazione del .h risolto per me.

+0

Nella libreria, ho un h che fa riferimento a tutti gli altri file .h. Pertanto, l'app chiamante deve solo fare riferimento a quel particolare file .h per ottenere un riferimento a tutto ciò che si trova nella libreria. Posso trascinare il file di intestazione ClassA nel progetto dell'app e farne riferimento dal file .m. Ancora ottenere la stessa eccezione però. – 4thSpace

+0

Un'altra cosa che potresti voler provare è fare self.classA.downloadUrl. Questo errore è solitamente quello che ottieni quando una variabile viene inizializzata su nulla, come NSString * m. Viene impostato su alcuni int apparentemente casuali. Potresti provare a sovrascrivere il metodo init nella classe e impostarlo su nil. –

+0

Ho provato a sovrascrivere init ma il mio breakpoint non è mai stato colpito. Tuttavia, se salgo alla definizione su ClassA dove è alloc, va al file corretto e vedo il mio init personalizzato. – 4thSpace

0

Si dovrebbe notare che questo non è necessariamente il migliore modello di progettazione. Dal suo aspetto, si sta essenzialmente utilizzando il proprio Delegato app per memorizzare ciò che equivale a una variabile globale.

Matt Gallagher coperto la questione della globali bene nel suo cacao dell'articolo Amore al http://cocoawithlove.com/2008/11/singletons-appdelegates-and-top-level.html. In tutta probabilità, la tua ClasseA dovrebbe essere un singleton piuttosto che un globale in AppDelegate, sebbene sia possibile che tu intenda ClassA come uno scopo più generale e non semplicemente un singleton. In quel caso, si sarebbe probabilmente meglio con sia un metodo di classe per restituire un'istanza preconfigurata di Classe A, qualcosa di simile a:

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

Oppure, in alternativa (dal momento che aggiungerebbe roba specifica applicazione per ciò che è probabilmente una classe generica), creare una nuova classe il cui unico scopo è quello di contenere quel metodo di classe.

Il punto è che le applicazioni globali non devono necessariamente far parte di AppDelegate. Solo perché AppDelegate è un singleton conosciuto, non significa che ogni altra app globale dovrebbe essere mescolata con essa anche se non hanno nulla a che fare concettualmente con la gestione dei metodi delegati di NSApplication.

+1

Irrilevante da rilasciare a portata di mano. – Justicle

18

Set bandiera -ObjC in altra bandiera linker nel vostro ambiente di progetto ...(Non nel progetto di libreria statico ma nel progetto che si sta utilizzando la libreria statica ...) E assicurarsi che nell'impostazione Progetto la configurazione sia impostata su Tutta la configurazione

+0

Ho appena creato una libreria statica con un target non più disponibile in Xcode4.2. Ho dovuto aggiungere "-ObjC" a "Other Linker Flags". Ora le corse inedite. – neoneye

+0

Questa era la soluzione per me !!! Grazie. – Xtro

0

Molto strano, ma. Devi dichiarare la classe per l'istanza dell'applicazione come myApplication: UIApplication anziché myApplication: NSObject. Sembra che il protocollo UIApplicationDelegate non implementa il messaggio + registerForSystemEvents. API Apple pazzesche, ancora.

14

Un sacco di persone hanno fornito risposte molto tecniche per questo e domande simili, ma penso che sia più semplice di così. A volte, se non stai prestando attenzione, un selettore che non intendi utilizzare può essere collegato a qualcosa nell'interfaccia. Potresti ricevere questo errore perché il selettore è lì ma non hai scritto alcun codice per questo.

Il modo più semplice per verificare che non sia il caso è fare clic tenendo premuto il tasto Controllo sull'elemento in modo da poter visualizzare tutti i selettori ad esso associati. Se c'è qualcosa lì dentro che non vuoi essere, sbarazzatene! Spero che questo aiuti ...

+0

Alla fine di una lunga giornata, questo era esattamente quello che avevo bisogno di vedere. Grazie per averlo semplificato. – jeremytripp

+0

Ho appena avuto questo nel mio primo progetto iOS. Ho avuto un "collegamento" morto a un'implementazione di azioni nel mio controller di visualizzazione. Rimosso, e ha funzionato. Grazie! –

+0

Bingo - esattamente quello di cui avevo bisogno! Grazie! – Kenny

1

Per me, ciò che ha causato questo errore è stato che ho accidentalmente inviato lo stesso messaggio due volte allo stesso membro della classe. Quando ho fatto clic con il tasto destro sul pulsante nella GUI, ho potuto vedere il nome del metodo due volte e ne ho cancellato uno. Errore mio principiante nel mio caso, ma volevo farlo fuori per altri neofiti da considerare.

1

Il mio era qualcosa di semplice/stupido. Errore newbie, per chiunque abbia convertito NSManagedObject in un normale NSObject.

ho avuto:

@dynamic order_id; 

quando ho dovuto avere:

@synthesize order_id; 
Problemi correlati