簡體   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