2011-08-16 14 views
5

sto provando a passare un selettore come parametro ed eseguirlo in seguito. Ma ottengo un errore di SIGABRT quando provo a chiamare il selettore con il successivo errore nella console:Objective-C: passare il selettore come parametro e quindi chiamarlo

terminazione app a causa di eccezione non identificata 'NSInvalidArgumentException', la ragione: '- [HttpRequest OnFinishConn:]: selettore non riconosciuta inviato esempio 0x7834c80'

HttpRequest.h

#import <Foundation/Foundation.h> 

@interface HttpRequest : NSObject 
{ 
    @private SEL onEndSel; 
    @private NSMutableData* receivedData; 
} 
-(void) StartRequest:(NSString *) url 
      parameters:(NSString*) params 
      onEndSelector:(SEL) selector; 
@end 

HttpRequest.m

#import "HttpRequest.h" 

@implementation HttpRequest 

-(void) StartRequest:(NSString *)url 
      parameters:(NSString*)params 
      onEndSelector:(SEL)selector 
{ 
    receivedData = [[NSMutableData alloc] init]; 
    NSMutableURLRequest *request = 
    [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:url]]; 
    [request setHTTPMethod:@"POST"]; 
    [request setHTTPBody:[params dataUsingEncoding:NSUTF8StringEncoding]]; 
    onEndSel = selector; 
    NSURLConnection* conn = [[NSURLConnection alloc] initWithRequest:request delegate:self]; 


} 
-(void) connectionDidFinishLoading:(NSURLConnection*) connection 
{ 
    //NSLog([[NSString alloc] initWithData:receivedData encoding:NSUTF8StringEncoding]); 
    [self performSelector:onEndSel withObject:[[NSMutableData alloc] initWithData:receivedData]]; 
} 
-(void) connection:(NSURLConnection *)connection didReceiveData:(NSData *)data{ 
    [receivedData appendData:data];  
} 
@end 

AppDelegate.m

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 
{ 
    //self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; 
    // Override point for customization after application launch. 
    //self.window.backgroundColor = [UIColor whiteColor]; 
    HttpRequest* req = [[HttpRequest alloc] init]; 
    SEL mysel = @selector(OnFinishConn:); 
    NSString * url = [[NSString alloc] initWithString:@"http://www.google.es"]; 
    [req StartRequest:url parameters:@"a" onEndSelector:@selector(OnFinishConn:)]; 
    [self.window makeKeyAndVisible]; 

    return YES; 
} 
-(void)OnFinishConn:(NSMutableData *)data 
{ 
    NSLog([[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]); 
} 

Sono nuovo in Objective C, quindi per favore sii paziente.

+0

Mentre non è la risposta alla tua domanda, il fatto che tu stia facendo questa domanda, mi porta a raccomandarti di provare ASIHttpRequest, piuttosto che reinventare la ruota – Jonathan

risposta

6

Questo perché si sta tentando di utilizzare il modello target-action ma non si passa un obiettivo. In realtà raccomanderei l'approccio delegato, ma ecco un esempio di come dovrebbe essere la tua interfaccia.

@interface HttpRequest : NSObject 
{ 
    @private 
    id onEndTarget; //<- need to know who to send the message to (do not retain) 
    SEL onEndSel; 
    NSMutableData* receivedData; 
} 

//Accept the target here 
-(void) StartRequest:(NSString *) url 
      parameters:(NSString*) params 
      onEndTarget:(id)target 
      onEndSelector:(SEL) selector; 

//... implementation 

-(void) connectionDidFinishLoading:(NSURLConnection*) connection 
{ 
    [onEndTarget performSelector:onEndSel withObject:[[NSMutableData alloc] initWithData:receivedData]]; 
} 

//... 
//Inside App Delegate 
[req StartRequest:url parameters:@"a" onEndTarget:self onEndSelector:@selector(OnFinishConn:)]; 

Assicurarsi di non mantenere il parametro OnEndTarget poiché ciò potrebbe creare un ciclo di conservazione. Considera anche la possibilità di creare una proprietà come target, quindi se qualcosa viene fatto con la connessione prima di completarla può smettere di essere il delegato.

+0

Grazie a tutti per le tue risposte. Ha funzionato bene con il codice di Joe. – Payn3

+0

Contento di aver contribuito a contrassegnare una domanda come risposta una volta risolto il problema e benvenuto a StackOverflow !. – Joe

4

Si sta inviando il selettore a self, ma questo è in HttpRequest. Il selettore che stai tentando di chiamare è in AppDelegate. Quindi stai inviando il selettore a un oggetto che non lo implementa. Per risolvere il problema, è necessario memorizzare non solo il selettore, ma un puntatore all'oggetto a cui deve essere inviato il selettore.

1

Leggere la documentazione su NSInvocation o passare un blocco come parametro se il SO di destinazione lo supporta.

+0

Brilliant. Questa dovrebbe essere la risposta –

Problemi correlati