[英]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輸出提示出現了什么問題:
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.