2009-12-25 16 views
11

che sto cercando di risolvere una NSNetService (denominato "My_Mac") per un IP in un'applicazione di fondo con questo codice:delegati NSNetService non essere chiamato

NSNetService *service = [[NSNetService alloc] initWithDomain:@"local." type:@"_daap._tcp" name:@"My_Mac"]; 
[service setDelegate:self]; 
[service resolveWithTimeout:5]; 

E nella stessa classe, non ho questi delegato metodi definiti:

- (void)netServiceDidResolveAddress:(NSNetService *)sender 
- (void)netService:(NSNetService *)sender didNotResolve:(NSDictionary *)errorDict 

ecco la parte strana: né metodi delegato vengono chiamati a meno che non corro una NSAlert dopo "[resolveWithTimeout servizio: 5];". Qualche idea?

risposta

9

Non sono sicuro, ma sembra che la richiesta non sia effettivamente programmata in un ciclo di esecuzione per qualche motivo. Forse provare qualcosa come this per programmarlo?

NSNetService *service = [[[NSNetService alloc] initWithDomain:@"local." type:@"_daap._tcp." name:@"My_Mac"] autorelease]; 
[service setDelegate:self]; 
[service scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:@"PrivateMyMacServiceMode"]; 
[service resolveWithTimeout:8.0]; 

domanda stupida, ma stai implementando esplicitamente NSServiceDelegate protocollo o semplicemente avere i metodi?

EDIT: Avevo un'altra idea che potesse trattarsi di una sorta di condizione di gara (uno scenario più probabile). I delegati sono di solito riferimenti deboli. Se il tuo oggetto sta uscendo dall'ambito ed è automaticamente rilasciato, il sistema finirà con un handle nullo e invierà i messaggi a zero. Nel caso in cui mostri un NSAlert (o esegui altri lavori), il tuo oggetto potrebbe rimanere sospeso abbastanza a lungo da far sì che i messaggi vengano richiamati. Potresti confermare che il tuo oggetto rimane in agguato per 8 secondi?

+0

Grazie per la risposta slf. Ho provato il codice NSRunLoop che avevi, ma nessun dado. Ho solo i metodi dato che ho come target 10.5 che non ha il protocollo formale NSServiceDelegate definito. –

+2

slf: hai ragione - Ho disattivato GC per assicurarmi che l'oggetto fosse ancora lì e che i delegati siano stati chiamati. Ora devo solo rintracciare dove è stato autorizzato automaticamente, poiché ho esplicitamente provato a mantenerlo, e questo non ha funzionato. Grazie per avermi indicato nella giusta direzione! –

+0

la soluzione a problemi apparentemente complessi è in genere più semplice di quanto si pensi :) – slf

23

Se si utilizza ARC, è necessario conservare l'oggetto servizio da qualche parte. Nel tuo esempio, l'oggetto servizio molto probabilmente esce dall'ambito e non viene fatto riferimento in nessun'altra parte del codice, quindi il compilatore proverà a rilasciarlo immediatamente dopo la chiamata di risoluzione.

Aggiungere una proprietà:

@property (nonatomic, strong) NSMutableArray *services; 

Nel vostro delegato, o dovunque si utilizza NSNetService

- (void)netServiceBrowser:(NSNetServiceBrowser *)browser 
      didFindService:(NSNetService *)aNetService 
       moreComing:(BOOL)moreComing 
{ 
    if (!self.services) { 
     self.services = [[NSMutableArray alloc] init]; 
    } 
    [self.services addObject:aNetService]; 
    [aNetService setDelegate:self]; 
    [aNetService resolveWithTimeout:3.0]; 
} 

Non dimenticare di fermarsi e rilasciare tali servizi una volta che sei finito o sbarazzarsi di il delegato:

for (NSNetService* service in self.services) { 
    [service stop]; 
} 
[self.services removeAllObjects]; 
+0

questo ha funzionato per me! – joshblour

+0

che lo mantiene funzionante. Ma il parametro NSNetService nelle firme del metodo NSNetServiceDelegate non mantiene l'oggetto? per esempio. ** mittente ** in '- (void) netServiceDidResolveAddress: (NSNetService *) mittente' – snowbound

Problemi correlati