繁体   English   中英

在非ARC项目中释放对象,对象在ARC库中声明

[英]Release an object in a non-ARC project, object is declared in an ARC library

那么我正在研究一个非ARC项目,但是使用了使用ARC编写的Philipp Kyeck的socketio库 我正在使用教程中介绍的方法合并非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

回答你的问题:

如果您使用非ARC代码中的ARC管理对象,则可以像使用非ARC对象一样使用它:如果您创建或保留它,则必须释放或自动释放它。

关于你的问题:

在您的评论中,您提到过您试图通过这样的初始化来解决问题

self.chatSockIO = [[[SocketIO alloc] initWithDelegate:self] autorelease];

并在socketIODidDisconnect

self.chatSockIO = nil;

如果chatSockIO属性具有retain语义,并且一次只使用一个SocketIO对象,那应该可以正常工作。

Zombie输出提示出现了什么问题:

  • 在倒数第二行中,释放对象,保留计数降为0,并释放对象。 这就是你所期望的。
  • 但是,在最后一行中,尝试从运行循环中保留对象。 你知道这是一个保留,因为没有NSZombie你会得到例外。
  • 这意味着虽然你完成了对象,它仍然会从某个地方接收调用。 这是出乎意料的。

它可能是您代码中的某些内容,也可能是您正在使用的某个库中的错误。 只是预感:在SocketIO.m替换-onDisconnect这些行

if (_webSocket != nil) {
    [_webSocket close];
}

if (_webSocket != nil) {
    [_webSocket close];
    _webSocket.delegate = nil;
}

这可能无法解决您的问题,但无论如何,它通常是一个在委托调用中释放对象的可怕想法 - 它可能在仍然工作时被释放,特别是如果对象在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项目,其他人已成功完成相反的操作。

根据我的经验,我不会混合ARC和非ARC期望小块的代码。 我浪费了很多时间来试图找到泄漏和崩溃的错误。

如果您无法将程序转换为ARC,请考虑使用非ARC版本的sockIO: https//github.com/pkyeck/socket.IO-objc/tree/non-arc

这可能会为你节省很多麻烦。

我有类似的问题。 我通过在类上设置@property(nonatomic, retain)来解决这个问题。 在你的情况下它应该是,

在.h

  @property(nonatomic, retain) SockIO *socketIO;

在.m

   @synthesize socketIO;
   chatSockIO = [[SocketIO alloc] initWithDelegate:self];

而且你不会再次崩溃你的应用程序!

ARC和非ARC对象混合得很好。 使用ARC实现的类可以安全地从非ARC代码中使用。 每当出现所有权错误时,问题可能在您的代码中。

没有看到代码就不可能找到错误,但它可能是一些简单的过度释放。

查看MyProject中仪器跟踪显示Release事件的所有位置,如-[SocketIO setTimeout]-[SocketIO onDisconnect]-[MyViewController socketIODidDisconnect:] 检查是否存在不正确的所有权转移,例如分配由保留属性或类似处理的实例变量。

我目前正在开发一个项目,我做了类似的事情,我解决它的方法是将非ARC项目切换到ARC。 Xcode为您转移所有内容,并为我解决了所有内存泄漏和其他问题。

要切换到ARC,您需要:

1.单击编辑 - >重构 - >转换为Objective-C ARC

2.单击项目目标,然后在下拉列表中选择要转换为ARC的文件

3.选择正确的文件后,单击“检查”

4.单击“下一步”,等待转换完成。

5.单击“更新”按钮以更新代码。

6.检查您的代码

希望有所帮助。 它帮助了我

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM