Ios 未调用AsyncSocket委托
我正在尝试编写一个应用程序,通过CocoaAsyncSocket库发送/接收数据 在应用程序的第一个版本中,在视图控制器中创建/初始化套接字,我还将正确调用的委托方法放在其中: WakmanFirstViewController.mIos 未调用AsyncSocket委托,ios,delegates,cocoaasyncsocket,Ios,Delegates,Cocoaasyncsocket,我正在尝试编写一个应用程序,通过CocoaAsyncSocket库发送/接收数据 在应用程序的第一个版本中,在视图控制器中创建/初始化套接字,我还将正确调用的委托方法放在其中: WakmanFirstViewController.m #import "WakmanFirstViewController.h" #import "GCDAsyncSocket.h" @implementation WakmanFirstViewController - (void)viewDidLoad {
#import "WakmanFirstViewController.h"
#import "GCDAsyncSocket.h"
@implementation WakmanFirstViewController
- (void)viewDidLoad
{
[super viewDidLoad];
asyncSocket = [[GCDAsyncSocket alloc] initWithDelegate:self delegateQueue:dispatch_get_main_queue()];
NSError *error = nil;
if (![asyncSocket connectToHost:@"192.168.1.13" onPort:2000 error:&error]) {
NSLog(@"Unable to connect to due to invalid configuration: %@",error);
}
NSData *requestData = [@"C" dataUsingEncoding:NSUTF8StringEncoding];
[asyncSocket writeData:requestData withTimeout:-1.0 tag:0];
[asyncSocket readDataWithTimeout:1 tag:0];
}
- (void)socket:(GCDAsyncSocket *)sock didConnectToHost:(NSString *)host port:(UInt16)port {
NSLog(@"socket:didConnectToHost:%@ port:%hu", host, port);
}
... (other delegate methods)
#import "SocketConnection.h"
static GCDAsyncSocket *socket;
@implementation SocketConnection
+ (GCDAsyncSocket *)getInstance
{
@synchronized(self) {
if (socket == nil) {
socket = [[GCDAsyncSocket alloc] initWithDelegate:self delegateQueue:dispatch_get_main_queue()];
}
if (![socket isConnected]) {
NSError *error = nil;
if (![socket connectToHost:@"192.168.1.13" onPort:2000 error:&error]){
NSLog(@"Error connecting: %@", error);
}
}
}
return socket;
}
- (void)socket:(GCDAsyncSocket *)sock didConnectToHost:(NSString *)host port:(UInt16)port {
NSLog(@"socket connected");
}
... (other delegate methods)
#import "WakmanFirstViewController.h"
@implementation WakmanFirstViewController
- (void)viewDidLoad
{
[super viewDidLoad];
socket = [SocketConnection getInstance];
NSData *requestData = [@"C" dataUsingEncoding:NSUTF8StringEncoding];
[asyncSocket writeData:requestData withTimeout:-1.0 tag:0];
[asyncSocket readDataWithTimeout:1 tag:0];
}
现在,我试图从ViewController中删除套接字的创建,并将其放在一个Singleton类中,以便我也可以从其他视图使用相同的连接
为此,我创建了一个新类(SocketConnection),并在其中移动了委托方法:
wakmanSocketConnection.h
#import <Foundation/Foundation.h>
#import "GCDAsyncSocket.h"
@interface SocketConnection : NSObject {
}
+ (GCDAsyncSocket *)getInstance;
@end
#import <UIKit/UIKit.h>
#import "SocketConnection.h"
@class GCDAsyncSocket;
@interface WakmanFirstViewController : UIViewController {
GCDAsyncSocket *socket;
}
@end
然后,我修改了Viewcontroller:
WakmanFirstViewController.h
#import <Foundation/Foundation.h>
#import "GCDAsyncSocket.h"
@interface SocketConnection : NSObject {
}
+ (GCDAsyncSocket *)getInstance;
@end
#import <UIKit/UIKit.h>
#import "SocketConnection.h"
@class GCDAsyncSocket;
@interface WakmanFirstViewController : UIViewController {
GCDAsyncSocket *socket;
}
@end
已建立连接,但问题是未调用委托方法
在wakmanSocketConnection.m中,我将委托设置为self,因此它应该引用我复制方法的类
有人能帮我找到这个问题吗
谢谢,
Corrado问题在于didReadData委托方法只被调用一次,您必须通过调用以下命令来保持侦听套接字:
[_socket readDataWithTimeout:-1 tag:0];
我的方法是这样的:
- (void)socket:(GCDAsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag
{
dispatch_async(dispatch_get_main_queue(), ^{
@autoreleasepool {
// DO STH
[_socket readDataWithTimeout:-1 tag:0];
}
});
}
初始方法:
- (id)init
{
if (self = [super init])
{
_socketQueue = dispatch_queue_create("Socket TCP Queue", nil);
_delegateQueue = dispatch_queue_create("Socket Delegate Queue", nil);
_socket = [[GCDAsyncSocket alloc] initWithDelegate:self delegateQueue:_delegateQueue socketQueue:_socketQueue];
}
return self;
}
和连接方法:
- (void)connectToServer:(NSString *)host port:(NSInteger)port
{
self.host = host;
self.port = port;
NSError *error = nil;
if (![_socket connectToHost:host onPort:port error:&error])
{
}
}
写入方法:
- (void)writeData:(NSData *)data withTimeout:(NSTimeInterval)timeout tag:(long)tag
{
if ([self.socket isConnected]) {
[self.socket writeData:data withTimeout:timeout tag:tag];
}
}
问题是didReadData委托方法只被调用一次,您必须通过调用以下命令来保持侦听套接字:
[_socket readDataWithTimeout:-1 tag:0];
我的方法是这样的:
- (void)socket:(GCDAsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag
{
dispatch_async(dispatch_get_main_queue(), ^{
@autoreleasepool {
// DO STH
[_socket readDataWithTimeout:-1 tag:0];
}
});
}
初始方法:
- (id)init
{
if (self = [super init])
{
_socketQueue = dispatch_queue_create("Socket TCP Queue", nil);
_delegateQueue = dispatch_queue_create("Socket Delegate Queue", nil);
_socket = [[GCDAsyncSocket alloc] initWithDelegate:self delegateQueue:_delegateQueue socketQueue:_socketQueue];
}
return self;
}
和连接方法:
- (void)connectToServer:(NSString *)host port:(NSInteger)port
{
self.host = host;
self.port = port;
NSError *error = nil;
if (![_socket connectToHost:host onPort:port error:&error])
{
}
}
写入方法:
- (void)writeData:(NSData *)data withTimeout:(NSTimeInterval)timeout tag:(long)tag
{
if ([self.socket isConnected]) {
[self.socket writeData:data withTimeout:timeout tag:tag];
}
}
谢谢你的回答,但我不明白两件事:1。如果这就是问题所在,为什么应用程序的第一个版本(包括VievController中的委托方法)工作得很好?代码完全相同。2.除了接收数据的方法外,似乎还有以下方法:-(void)socket:(GCDAsyncSocket*)sock didConnectToHost:(NSString*)主机端口:(UInt16)端口{NSLog(@“socket connected”);}不工作,因为我在日志中看不到“socket connected”(但连接是建立的,因为我在另一侧收到了字母“C”)感谢您的单例模式错误,您应该在getInstance中返回SocketConnection指针,而不是GCDAsyncSocket!您没有创建SocketConnection类,因此委托将为零。再次感谢,我将按照您的建议进行操作。您是否解决过此问题@Corrado,我希望完成类似的任务感谢您的回答,但我不明白两件事:1。如果这就是问题所在,为什么应用程序的第一个版本(包括VievController中的委托方法)工作得很好?代码完全相同。2.除了接收数据的方法外,似乎还有以下方法:-(void)socket:(GCDAsyncSocket*)sock didConnectToHost:(NSString*)主机端口:(UInt16)端口{NSLog(@“socket connected”);}不工作,因为我在日志中看不到“socket connected”(但连接是建立的,因为我在另一侧收到了字母“C”)感谢您的单例模式错误,您应该在getInstance中返回SocketConnection指针,而不是GCDAsyncSocket!您没有创建SocketConnection类,因此委托将为零。再次感谢您,我将按照您的建议进行操作。您曾经解决过这个@Corrado问题吗?我希望完成类似的任务