2009-12-25 15 views
11

Ich versuche, eine NSNetService (genannt „My_Mac“) zu einer IP in einem Hintergrund-App mit diesem Code zu beheben:NSNetService Delegierten nicht genannt zu werden

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

Und in der gleichen Klasse, ich habe diese Delegierten Methoden definiert:

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

Hier ist der seltsame Teil: weder Delegatmethoden aufgerufen, wenn ich einen NSAlert nach laufen „[Dienst resolveWithTimeout: 5];“. Irgendwelche Ideen?

Antwort

9

Ich bin mir nicht sicher, aber es sieht so aus, als ob die Anfrage aus irgendeinem Grund nicht in einer Laufschleife geplant ist. Vielleicht versuchen Sie etwas wie this, um es zu planen?

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]; 

Dumme Frage, aber setzen Sie explizit NSServiceDelegate Protokoll oder einfach nur die Methoden?

EDIT: Ich hatte einen anderen Gedanken, dass dies eine Art von Race Condition sein könnte (ein wahrscheinlicheres Szenario). Delegierte sind normalerweise schwache Referenzen. Wenn Ihr Objekt den Gültigkeitsbereich verlässt und automatisch freigegeben wird, würde das System mit einem Nul-Handle enden und die Nachrichten auf Null setzen. In dem Fall, in dem Sie ein NSAlert zeigen (oder andere Arbeiten machen), hängt Ihr Objekt möglicherweise gerade so lange herum, dass es die Nachrichten zurückbekommt. Kannst du bestätigen, dass dein Objekt die ganzen 8 Sekunden lang herumsteht?

+0

Danke für die Antwort slf. Ich habe den NSRunLoop-Code ausprobiert, den Sie hatten, aber keine Würfel. Ich habe nur die Methoden, da ich 10.5 anvisiere, die das formelle NSServiceDelegate-Protokoll nicht definiert haben. –

+2

slf: Sie haben Recht - Ich habe GC ausgeschaltet, um sicherzustellen, dass das Objekt noch da war und die Delegierten angerufen wurden. Jetzt muss ich nur noch herausfinden, wo es wieder freigegeben wird, da ich explizit versucht habe, es zu behalten, und das hat nicht funktioniert. Danke, dass Sie mich in die richtige Richtung weisen! –

+0

die Lösung für scheinbar komplexe Probleme ist in der Regel einfacher als Sie zuerst denken :) – slf

23

Wenn Sie ARC verwenden, müssen Sie das Serviceobjekt irgendwo aufbewahren. In Ihrem Beispiel wird das Service-Objekt höchstwahrscheinlich den Gültigkeitsbereich verlassen und nirgendwo anders im Code referenziert. Daher wird der Compiler versuchen, es sofort nach dem Auflösungsaufruf freizugeben.

hinzufügen Immobilie:

@property (nonatomic, strong) NSMutableArray *services; 

In Ihrem Delegierten, oder wo auch immer verwenden Sie 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]; 
} 

Vergessen Sie nicht, diese Dienste zu beenden und lassen Sie, wenn Sie fertig sind oder loszuwerden der Delegierte:

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

das hat für mich funktioniert! – joshblour

+0

Beibehaltung funktioniert. Aber behält der NSNetService-Parameter in den NSNetServiceDelegate-Methodensignaturen das Objekt nicht bei? z.B. ** Absender ** in '- (void) netServiceDidResolveAddress: (NSNetService *) sender' – snowbound

Verwandte Themen