6

さて、私は非ARCプロジェクトに取り組んでいますが、ARCを使用して作成されたPhilippKyeckの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メソッドを使用して定義されたオブジェクトを使用する場合の通常の方法は何ですか。割り当てるだけですか、それとも使用後に割り当てて解放する必要がありますか?

編集:いくつかのより多くの情報。

クラッシュ時にゾンビインストゥルメントを実行しました。これは、それが言わなければならなかったことです。これは、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
4

6 に答える 6

3

あなたの質問に答えるには:

非ARCコードからARC管理対象オブジェクトを使用する場合は、非ARCオブジェクトを使用する場合と同じように使用します。作成または保持する場合は、リリースまたは自動リリースする必要があります。

あなたの問題について:

あなたのコメントの中で、あなたはこのように初期化することで問題を修正しようとしたと述べました

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

とでsocketIODidDisconnect

self.chatSockIO = nil;

chatSockIOプロパティにretainセマンティクスがあり、一度に1つのSocketIOオブジェクトのみが使用される場合、これは正常に機能するはずです。

ゾンビの出力は、何が問題になっているのかについてのヒントを提供します。

  • 最後から2番目の行で、オブジェクトを解放すると、保持カウントが0に下がり、オブジェクトの割り当てが解除されます。それはあなたが期待することです。
  • ただし、最後の行では、実行ループからオブジェクトを保持しようとしています。あなたはそれがあなたがなしで得る例外のために保持であることを知っていますNSZombie
  • つまり、オブジェクトは完成しましたが、それでもどこかから呼び出しを受信します。これは予想外です。

コードに何かがあるか、使用しているライブラリの1つにエラーがある可能性があります。ただの予感:SocketIO.mこれらの行を次のように置き換えます-onDisconnect

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

if (_webSocket != nil) {
    [_webSocket close];
    _webSocket.delegate = nil;
}
于 2012-07-19T10:35:24.220 に答える
1

これは問題を解決しないかもしれませんが、いずれにせよ、デリゲート呼び出しでオブジェクトを解放することは通常ひどい考えです-それはまだ作業をしている間にdeallocされる可能性があり、特にオブジェクトがARCの下にある場合は、deallocがない可能性があります方法。

したがって、クローズデリゲート呼び出しを次のように変換します。

- (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アプリでいくつかの非ARCプロジェクトを使用しましたが、他のプロジェクトはその逆を成功させました。

于 2012-07-19T21:37:03.427 に答える
0

ARCオブジェクトと非ARCオブジェクトはうまく混ざり合っています。ARCを使用して実装されたクラスは、ARC以外のコードから安全に使用できます。所有権エラーがあるときはいつでも、問題はおそらくあなたのコードにあります。

コードを見ないとエラーを見つけることはできませんが、おそらく単純なオーバーリリースです。

MyProjectInstrumentsトレースが、、などのイベントを示しているすべてReleaseの場所を確認します。保持プロパティなどによって処理されるインスタンス変数を割り当てるなど、不適切な所有権の譲渡がないかどうかを確認します。-[SocketIO setTimeout]-[SocketIO onDisconnect]-[MyViewController socketIODidDisconnect:]

于 2012-07-16T08:39:17.087 に答える
0

私の経験では、ARCと非ARCを混在させることはなく、コードの小さな小さなチャンクを期待しています。リークやクラッシュバグを見つけるために多くの時間を無駄にしました。

プログラムをARCに変換できない場合は、ARC以外のバージョンのsockIOの使用を検討してください:https ://github.com/pkyeck/socket.IO-objc/tree/non-arc

それはおそらくあなたに多くの頭痛を救うでしょう。

于 2012-07-11T08:51:50.387 に答える
0

私も同様の問題を感じていました。@property(nonatomic, retain) クラスを設定することでこれを解決しました。あなたの場合はそうあるべきです、

.hで

  @property(nonatomic, retain) SockIO *socketIO;

.mで

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

そして、あなたは再びあなたのアプリをクラッシュさせることはありません!

于 2012-07-16T08:02:51.827 に答える
0

私は現在、似たようなことをしたプロジェクトに取り組んでいます。それを解決する方法は、非ARCプロジェクトをARCに切り替えることでした。Xcodeはあなたのためにすべてを転送し、私にとってはすべてのメモリリークやその他の問題を解決しました。

ARCに切り替えるには、次のことを行う必要があります。

1. [編集]->[リファクタリング]->[Objective-CARCに変換]をクリックします

2.プロジェクトのターゲットをクリックし、ドロップダウンで、ARCに変換するファイルを選択します

3.適切なファイルを選択したら、[チェック]をクリックします

4. [次へ]をクリックして、変換が完了するまで待ちます。

5. [更新]ボタンをクリックして、コードを更新します。

6.コードを確認します

お役に立てば幸いです。それは私を助けました

于 2012-07-16T19:22:10.800 に答える