NSNotification Strangeness при использовании в сочетании с AsyncSocket - PullRequest
0 голосов
/ 28 июня 2009

Я использую AsyncSocket для подключения к серверу из приложения для iPhone. В делегате, который получил данные с сервера, я публикую уведомление, которое сообщит делегату tableView, чтобы он вызывал reloadData для tableView:

- (void)onSocket:(AsyncSocket *)sock didReadData:(NSData*)data withTag:(long)tag {
    [[NSNotificationCenter defaultCenter] postNotificationName:@"PEERSTATUSCHANGED" object:self];
    [sock readDataToData:[AsyncSocket CRLFData] withTimeout:-1 tag:0];
}

и в viewController:

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
    if (self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]) {
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(peerStatusDidChange:) name:@"PEERSTATUSCHANGED" object:nil];
    }
    return self;
}


- (void)peerStatusDidChange:(NSNotification *)notification {
    NSLog(@"NOTIFICATION RECEIVED");
}

Так вот, это вообще не работает. Уведомление выставлено, но не распознано ViewController. Однако, когда я делаю то же самое в applicationDidFinishLaunching:

- (void)applicationDidFinishLaunching:(UIApplication *)application {    

protocol = [[XBBProtocol alloc] init];

SourceListViewController *sourceListVC = [[[SourceListViewController alloc] initWithNibName:@"SourceListViewController" bundle:nil] autorelease];
UINavigationController *navigationController = [[[UINavigationController alloc] initWithRootViewController:sourceListVC] autorelease];

[[NSNotificationCenter defaultCenter] postNotificationName:@"PEERSTATUSCHANGED" object:self];
[protocol connectToServer];

// Override point for customization after application launch
[window addSubview:[navigationController view]];
[window makeKeyAndVisible];
}

Я получил уведомление, полученное в viewController.

Кто-нибудь знает почему? это как-то связано с методами делегата AsyncSocket в другом потоке?

Заранее спасибо.

Ответы [ 2 ]

1 голос
/ 29 июня 2009

Попробуйте поместить метод, который отправляет уведомление, в другой метод и вызвать его с "executeSelectorOnMainThread". Весьма вероятно, что ваш сетевой код вызывается в фоновом потоке, и поэтому при срабатывании уведомления он сообщает табличному представлению в том же потоке ...

Вы не можете делать вызовы пользовательского интерфейса ни для чего, кроме основного потока.

1 голос
/ 28 июня 2009

Одна из возможностей заключается в том, что ваш initWithNibName:bundle: метод на самом деле не вызывается. Если вы создаете экземпляр контроллера представления в NIB (а не в коде), то вместо этого он вызывает initWithCoder:.

Быстрый способ проверки - установить точку останова в initWithNibName:bundle:.

...