1

我正在为 iPhone 上的音频服务器编写控制器。每个“视图”通常需要作为客户端从 TCP/IP 套接字获取数据。我有一个使用AsyncSocket类的类的套接字。(在尝试让套接字客户端工作的时间超过我想承认的时间之后,这是一个非常令人印象深刻和有用的类)。这需要编写委托函数来接收数据......

- (void)onSocket:(AsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag

我有一个标准表视图界面,​​我在一个视图上看到了一个艺术家列表,然后选择艺术家时,我会在下一个视图上移动到专辑,依此类推。

我的问题是:当我从一个视图转到另一个视图时,发送和接收数据的最佳方式是什么?我需要为每个视图类创建一个全新的套接字吗?(似乎有点过头了)以某种方式再次链接本地接收器委托?

我似乎想不出让这个在 1 类之外工作的“正确”方法,并且关于 iphone 上的套接字客户端通信的在线信息并不多。

4

2 回答 2

2

听起来您希望多个对象接收委托方法,对吗?在 Mac OS X 上,解决方案是使用通知系统。我没有看过这个AsyncSocket类,但它看起来只支持开箱即用的委托。

通知很棒,因为它们让一个对象将信息广播给任何其他有兴趣接收它的对象。对象在通知中心注册自己,以便在发布特定通知时得到通知。您可以通过实现自己的类来轻松添加此功能 wrap AsyncSocket

这就是你要做的。您将编写自己的类,该类具有AsyncSocket作为实例变量。您可以将此类设置为AsyncSocket对象的委托。然后,当调用委托方法时,您会将通知发布到NSNotificationCenter. 您可能需要将委托方法中的参数填充到通知的userInfo字典中。

另一方面,您的视图控制器将NSNotificationCenter作为观察者注册您的自定义类发送的通知。然后,每次委托方法触发时,每个视图控制器都会收到该事件的通知。

说够了;这是一些代码:

extern NSString *const AsyncSocketDidReadData;

@interface MySocketWrapper : NSObject { // give this class a better name ;-)
    AsyncSocket *socket;
}

@property (nonatomic, readonly) socket;

@end

在 .m 文件中:

NSString *const AsyncSocketDidReadData = @"AsyncSocketDidReadData";

@implementation MySocketWrapper

@synthesize socket;

- (id)init {
    if (![super init]) return nil;

    socket = [[AsyncSocket alloc] init]; // initialize this however you want
    [socket setDelegate:self];
    return self;
}

- (void)onSocket:(AsyncSocket *)aSocket didReadData:(NSData *)data withTag:(long)tag {
    NSDictionary *userInfo = 
         [NSDictionary dictionaryWithObjectsAndKeys:
          data, @"data",
          [NSNumber numberWithLong:tag], @"tag",
          nil];
    [[NSNotificationCenter defaultCenter] postNotificationName:AsyncSocketDidReadData object:self.socket userInfo:userInfo];
}

@end

最后,在您的各种视图控制器中,您可以编写如下代码:

- (id)initWithNibName:(NSString *)nibName bundle:(NSBundle *)bundle {
    if (![super initWithNibName:nibName bundle:bundle]) return nil;

    // Do any initalization you need here

    // Note that if you specify 'nil' for object, you'll be sent notifications for every MySocketWrapper object.
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(asyncSocketDidReadData:) notification:AsyncSocketDidReadData object:nil]; 

    return self;
}

- (void)asyncSocketDidReadData:(NSNotification *)notification {
    AsyncSocket *socket = [[notification object] socket];
    NSData *theData = [[notification userInfo] objectForKey:@"data"];
    long tag = [[[notification userInfo] objectForKey:@"tag"] longValue];

    // Do what you want with the data here
}

显然,这段代码并不完全完整,而且我可能弄错了一些方法名称(我是凭记忆做的),但这是一个适合您的解决方案。

于 2009-03-24T17:03:27.707 回答
0

前面的答案很好,但视图控制器片段中的“通知:”应该是“名称:”。

于 2009-07-21T05:51:37.170 回答