我正在开发一个非ARC项目,但是使用使用ARC编写的Philipp Kyeck's socketio library。我正在使用this教程合并非ARC项目和ARC库中解释的方法。
在我的ViewController文件中,我正在使用
初始化套接字 SockIO *chatSockIO = [[SocketIO alloc] initWithDelegate:self];
当我需要断开连接时,我打电话给
[chatSockIO disconnect];
导致socketIODidDisconnect委托方法触发。
- (void) socketIODidDisconnect:(SocketIO *)socket{
[chatSockIO release]; ==> is this call needed?
}
现在我的问题是[chatSockIO release]
行。 我们是否需要释放一个自身在ARC模式下定义但在非ARC项目中使用的对象?
现在,当我尝试发布时,我得到一个例外
-[SocketIO retain]: message sent to deallocated instance 0x6fec370
但是当我注释掉那一行时,我的内存泄漏和我的库对象中的 dealloc根本没有被调用
忘记我提到的库,崩溃我的代码并泄漏.. 在非ARC项目中使用使用ARC方法定义的对象时的常规做法是什么。我应该只分配它,还是应该在使用后分配和释放它?
我在崩溃时运行zombie instrument,这就是它所说的..它显示了对alloc和release函数的调用。
# Address Category Event Type RefCt Timestamp Size Responsible Library Responsible Caller
0 0x72d5da0 SocketIO Malloc 1 00:09.700.274 64 MyProject -[MyViewController sendRequestForSocketIOPush]
1 0x72d5da0 SocketIO Retain 2 00:09.700.317 0 MyProject -[SocketIO initWithDelegate:]
2 0x72d5da0 SocketIO Release 1 00:09.700.320 0 MyProject -[SocketIO initWithDelegate:]
3 0x72d5da0 SocketIO Retain 2 00:09.700.440 0 Foundation -[NSURLConnectionInternal initWithInfo:]
4 0x72d5da0 SocketIO Retain 3 00:10.413.717 0 Foundation -[NSURLConnectionInternal _withConnectionAndDelegate:onlyActive:]
5 0x72d5da0 SocketIO Release 2 00:10.413.761 0 Foundation -[NSURLConnectionInternalConnection invokeForDelegate:]
6 0x72d5da0 SocketIO Retain 3 00:10.413.797 0 Foundation -[NSURLConnectionInternal _withConnectionAndDelegate:onlyActive:]
7 0x72d5da0 SocketIO Release 2 00:10.413.811 0 Foundation -[NSURLConnectionInternalConnection invokeForDelegate:]
8 0x72d5da0 SocketIO Retain 3 00:10.413.816 0 Foundation -[NSURLConnectionInternal _withConnectionAndDelegate:onlyActive:]
9 0x72d5da0 SocketIO Release 2 00:10.415.087 0 Foundation -[NSURLConnectionInternalConnection invokeForDelegate:]
10 0x72d5da0 SocketIO Retain 3 00:10.415.214 0 Foundation -[NSURLConnectionInternal _withConnectionAndDelegate:onlyActive:]
11 0x72d5da0 SocketIO Release 2 00:10.415.216 0 Foundation -[NSURLConnectionInternalConnection invokeForDelegate:]
12 0x72d5da0 SocketIO Release 1 00:10.415.275 0 Foundation -[NSURLConnectionInternalConnection invokeForDelegate:]
13 0x72d5da0 SocketIO Retain 2 00:10.969.432 0 GraphicsServices GSEventRunModal
14 0x72d5da0 SocketIO Release 1 00:10.969.433 0 GraphicsServices GSEventRunModal
15 0x72d5da0 SocketIO Retain 2 00:10.969.434 0 GraphicsServices GSEventRunModal
16 0x72d5da0 SocketIO Release 1 00:10.969.456 0 GraphicsServices GSEventRunModal
17 0x72d5da0 SocketIO Retain 2 00:10.969.459 0 GraphicsServices GSEventRunModal
18 0x72d5da0 SocketIO Retain 3 00:10.969.488 0 Foundation -[NSCFTimer initWithFireDate:interval:target:selector:userInfo:repeats:]
19 0x72d5da0 SocketIO Release 2 00:10.976.115 0 MyProject -[SocketIO setTimeout]
20 0x72d5da0 SocketIO Retain 3 00:10.976.125 0 Foundation -[NSCFTimer initWithFireDate:interval:target:selector:userInfo:repeats:]
21 0x72d5da0 SocketIO Release 2 00:10.976.161 0 GraphicsServices GSEventRunModal
22 0x72d5da0 SocketIO Retain 3 00:13.935.328 0 GraphicsServices GSEventRunModal
23 0x72d5da0 SocketIO Release 2 00:13.935.373 0 MyProject -[SocketIO setTimeout]
24 0x72d5da0 SocketIO Retain 3 00:13.935.399 0 Foundation -[NSCFTimer initWithFireDate:interval:target:selector:userInfo:repeats:]
25 0x72d5da0 SocketIO Release 2 00:13.935.685 0 MyProject -[SocketIO onDisconnect]
26 0x72d5da0 SocketIO Release 1 00:13.935.705 0 MyProject -[MyViewController socketIODidDisconnect:]
27 0x72d5da0 SocketIO Release 0 00:13.935.716 0 GraphicsServices GSEventRunModal
28 0x72d5da0 SocketIO Zombie -1 00:13.936.298 0 GraphicsServices GSEventRunModal
答案 0 :(得分:3)
回答您的问题:
如果您使用非ARC代码中的ARC管理对象,则可以像使用非ARC对象一样使用它:如果您创建或保留它,则必须释放或自动释放它。
关于您的问题:
在您的评论中,您提到您试图通过像这样初始化来解决问题
self.chatSockIO = [[[SocketIO alloc] initWithDelegate:self] autorelease];
并在socketIODidDisconnect
self.chatSockIO = nil;
如果chatSockIO
属性具有retain
语义,并且一次只使用一个SocketIO
对象,那应该可以正常工作。
Zombie输出提示出现了什么问题:
NSZombie
的例外。它可能是您代码中的某个内容,也可能是您正在使用的某个库中的错误。只是预感:在SocketIO.m
中替换-onDisconnect
if (_webSocket != nil) {
[_webSocket close];
}
与
if (_webSocket != nil) {
[_webSocket close];
_webSocket.delegate = nil;
}
答案 1 :(得分:1)
这可能无法解决您的问题,但无论如何,它通常是一个在委托调用中释放对象的可怕想法 - 它可能会在仍然工作时被释放,特别是如果对象在ARC下,可能不会有一个dealloc方法。
所以将你的close委托调用转换为:
- (void) socketIODidDisconnect:(SocketIO *)socket
{
chatSockIO.delegate = nil; // don't want any more messages
dispatch_async(dispatch_get_main_gueue(), ^{ self.chatSockIO = nil; }); // typed in text editor
// your question - is the release needed? Well, under virtually every scenario yes, but I don't know this framework
}
这是否能解决您的问题,您应该以这种方式进行发布 - 在代理返回后的主线程上。如果您查看代码,您应该像使用普通类一样完全使用此ARC类。互操作性非常好,我在ARC应用程序中使用了几个NON-ARC项目,其他人已成功完成相反的操作。
答案 2 :(得分:0)
根据我的经验,我不会混用ARC和非ARC期望小块的代码。我浪费了很多时间来试图找到泄漏和崩溃的错误。
如果您无法将程序转换为ARC,请考虑使用非ARC版本的sockIO:https://github.com/pkyeck/socket.IO-objc/tree/non-arc
这可能会让你免受很多麻烦。
答案 3 :(得分:0)
我有类似的问题。我通过在课堂上设置@property(nonatomic, retain)
来解决这个问题。在你的情况下应该是,
in .h
@property(nonatomic, retain) SockIO *socketIO;
in .m
@synthesize socketIO;
chatSockIO = [[SocketIO alloc] initWithDelegate:self];
你不会再次崩溃你的应用程序!
答案 4 :(得分:0)
ARC和非ARC对象混合均匀。使用ARC实现的类可以安全地从非ARC代码中使用。每当出现所有权错误时,问题可能在您的代码中。
如果没有看到代码,就无法找到错误,但这可能是一些简单的过度释放。
查看MyProject
中所有工具跟踪显示Release
事件的地方,例如-[SocketIO setTimeout]
,-[SocketIO onDisconnect]
和-[MyViewController socketIODidDisconnect:]
。检查是否存在不正确的所有权转移,例如分配由保留属性或类似处理的实例变量。
答案 5 :(得分:0)
我目前正在开展一个项目,我做了类似的事情,我解决它的方法是将非ARC项目切换到ARC。 Xcode为您传输了所有内容,并为我解决了所有内存泄漏和其他问题。
要切换到ARC,您需要:
1。点击编辑 - >重构 - >转换为Objective-C ARC
2. 点击您的项目目标,然后在下拉列表中选择要转换为ARC的文件
3. 一旦选择了正确的文件,请点击“检查”
4. 点击下一步并等待转换完成。
5. 点击“更新”按钮更新您的代码。
6。审核您的代码
希望有所帮助。它帮助了我