Делегатов NSNetService не вызывают - PullRequest
11 голосов
/ 25 декабря 2009

Я пытаюсь преобразовать NSNetService (с именем «My_Mac») в IP-адрес в фоновом приложении с помощью этого кода:

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

И в том же классе у меня определены следующие методы делегата:

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

Вот странная часть: ни один метод делегата не вызывается, если я не запускаю NSAlert после "[service resolWithTimeout: 5];". Есть идеи?

Ответы [ 3 ]

25 голосов
/ 21 апреля 2013

Если вы используете ARC, вам нужно где-то сохранить объект службы. В вашем примере объект службы, скорее всего, выходит из области видимости и не упоминается нигде в вашем коде, поэтому компилятор попытается освободить его сразу после вызова разрешения.

Добавить объект:

@property (nonatomic, strong) NSMutableArray *services;

В вашем делегате или везде, где вы используете 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];
}

Не забудьте остановить и освободить эти службы, как только вы закончите или избавитесь от делегата:

for (NSNetService* service in self.services) {
    [service stop];
}
[self.services removeAllObjects];
9 голосов
/ 25 декабря 2009

Я не уверен, но похоже, что запрос на самом деле не запланирован в цикле выполнения по какой-то причине. Может быть, попробовать что-то вроде это , чтобы запланировать это?

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

Глупый вопрос, но вы явно используете протокол NSServiceDelegate или просто используете методы?

РЕДАКТИРОВАТЬ: У меня была еще одна мысль, что это может быть какое-то состояние гонки (более вероятный сценарий). Делегаты, как правило, слабые ссылки. Если ваш объект выпадает из области видимости и автоматически высвобождается, система получит нулевой дескриптор и будет запускать сообщения до нуля. В случае, когда вы показываете NSAlert (или выполняете другую работу), ваш объект может висеть достаточно долго, чтобы он мог вернуть ему сообщения. Не могли бы вы подтвердить, что ваш объект торчит в течение полных 8 секунд?

0 голосов
/ 14 октября 2018

Я только что столкнулся с этой проблемой и уже удерживал объект NSNetService, так что это не было причиной.

Оказывается, это потому, что уровни доступа к методам делегатов, которые я определил, не соответствуют уровню доступа class (class был public, тогда как методы делегатов были internal). А поскольку все методы делегата являются необязательными, компилятор просто выдавал молчаливое предупреждение.

...