我遇到的问题比任何事情都更令人困惑。我正在尝试使用GCDAsyncSocket在Objective-C中建立套接字连接。当且仅当套接字变量被调用socket
时,发送到我的GCDAsyncSocket的connectToHost消息才会失败并显示EXC_BAD_ACCESS。它确实不是问题,因为我很容易使用不同的变量名称,但我很好奇为什么会发生这种情况。
我认为这是我的代码的相关部分,来自我创建的一个名为SocketManager的类。大部分代码都来自GCDAsyncSocket intro。下面的代码在指定行显示EXC_BAD_ACCESS失败。
#import "SocketManager.h"
#import "GCDAsyncSocket.h"
@implementation SocketManager
GCDAsyncSocket *socket;
-(id) init {
self = [super init];
socket = [[GCDAsyncSocket alloc] initWithDelegate:self delegateQueue:dispatch_get_main_queue()];
NSError *err = nil;
// EXC_BAD_ACCESS happens at the line below
if (![socket connectToHost:@"localhost" onPort:26400 error:&err]) NSLog(@"I goofed: %@", err);
NSLog(@"just created socket");
return self;
}
但是,如果我将变量名称从socket
更改为sock
或banana
或任何其他名称,则代码运行正常,这让我很奇怪。为什么会这样? socket
是某种保留的系统字吗?如果是这种情况,我希望代码根本不能编译,但我对Objective-C很新。
顺便说一句,我的didConnectToHost:
委托方法很少被调用,我认为这是一个单独的问题,但据我所知,它可能是相关的。
答案 0 :(得分:1)
正如@bburn所说,这是一个符号碰撞。 GCDAsyncSocket使用了一个BSD socket()函数。如果你看一下调试器中的EXC_BAD_ACCESS,你会发现它在尝试调用socket()时实际上是失败的,因为它正在将函数地址解析为你变量的函数地址。
除了重命名变量之外,你还可以做一些事情(我认为即使你也重命名这个变量,做这些事情也是个好主意):
要将其更改为私有成员变量,请更改:
@implementation Socketmanager
GCDAsyncSocket *socket;
到此:
@interface SocketManager()
{
GCDAsyncSocket *socket;
}
@end
@implementation SocketManager
...