0

私は NSURLConnection と、より一般的には SIGABRT のデバッグに関する投稿をたくさん探し回ってきましたが、これには満足できませんでした。どんな助けでも大歓迎です。

したがって、アプリの開始時にユーザーにログイン ビューが表示され、ユーザー名とパスワードを指定すると、LoginService クラスで次のようにして NSURLConnection を開始します。

-(void)loginWithURLRequest:(NSString*)requestString
{
    if(self.mConnection == nil)
    {
        NSURLRequest* request = [NSURLRequest requestWithURL:[NSURL URLWithString:requestString]
                                                 cachePolicy:NSURLRequestUseProtocolCachePolicy
                                             timeoutInterval:120.0];

        self.mConnection = [[[NSURLConnection alloc] initWithRequest:request delegate:self] autorelease];
    }
}

-(void)discardLoginDataAndPrepareToReceiveMore
{
    // Releases old mLoginData and assigns a new empty one.
    self.mLoginData = [[NSMutableData alloc] init];
}

-(void)connection:(NSURLConnection*)connection didReceiveResponse:(NSURLResponse*)response
{
    [self discardLoginDataAndPrepareToReceiveMore];
}

-(void)connection:(NSURLConnection*)connection didReceiveData:(NSData*)data
{
    [mLoginData appendData:data];
}

-(void)connection:(NSURLConnection*)connection didFailWithError:(NSError*)error
{
    [self discardLoginDataAndPrepareToReceiveMore];
    [mDelegate onLoginFailure:error];

    self.mConnection = nil;
}

-(void)connectionDidFinishLoading:(NSURLConnection*)connection
{   
    [mDataReader performSelector:mDataReaderSelector withObject:mLoginData];
    [mDelegate onLoggedInSuccessfully];

    self.mConnection = nil;
}

したがって、これはすべて正常に機能します。問題は後で (別のクラス内から) リクエストを POST しようとすると、その直後に別のスレッドでアセンブリのロード中に SIGABRT が発生してアプリがクラッシュし、コードをたどることができなくなります。NSURLConnection が別のスレッドなどで実行されていることに気付きました。

だから私はそれが私の郵便番号に何か問題があるのではないかと考え、それを以下のまったく同じログイン接続コードに置き換えました:

    NSString* requestString =  @"identical URL as before in login";

    NSURLRequest* request = [NSURLRequest requestWithURL:[NSURL URLWithString:requestString]
                                             cachePolicy:NSURLRequestUseProtocolCachePolicy
                                         timeoutInterval:120.0];

    self.mConnection = [[[NSURLConnection alloc] initWithRequest:request delegate:self] autorelease];

同じ問題なので、私の最後の試みは、どういうわけか最初のログインが混乱していないかどうかを確認することでした. つまり、接続について何も知らず、適切にクリーンアップしていなかったなどの可能性があります.

私が間違っている可能性があることに関するヒント。最初の接続が確立されている間/後に私がしていないことがあり、2番目の接続がクラッシュするようです。

最初のログインがまだ存在する場合、アプリで 2 番目の NSURConnection をステップ オーバーできます。実際のクラッシュは、この接続が確立された後に続行するようにアプリに指示した直後に発生します。

どちらの場合も、mConnection はそれぞれ各クラスの (非アトミックで保持された) プロパティです。

とにかくすぐに採用する必要がある複数の接続を処理するより良い方法があることを認識しています(検索した後)が、クライアントのデモでこれを機能させる必要があり、場合は、接続などの根本的な誤解を意味します。

うーん、これをデバッグする方法についても知識が不足していると思います。このための楽器のヒントをいただければ幸いです。私の理解が正しければ、SIGABRT はリークによって引き起こされる問題ではないため、パフォーマンス ツールでの割り当ての使用を避けましたか?

さらに、コールスタックは次のとおりです。

-#0 0x90d7e132 in kill
-#1 0x90d7e124 in kill$UNIX2003
-#2 0x90e108e5 in raise
-#3 0x90e2699c in abort
-#4 0x90d23d35 in free
-#5 0x026fc081 in __CFStringDeallocate
-#6 0x026fbccb in _CFRelease
-#7 0x02720c9d in _CFAutoreleasePoolPop
-#8 0x0004fe67 in -[NSAutoreleasePool release]
-#9 0x00300e7f in _UIApplicationHandleEvent
-#10 0x030c4822 in PurpleEventCallback
-#11 0x027c5ff4 in __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION

-#12 0x02726807 in __CFRunLoopDoSource1
-#13 0x02723a93 in __CFRunLoopRun
-#14 0x02723350 in CFRunLoopRunSpecific
-#15 0x02723271 CFRunLoopRunInMode
-#16 0x030c300c GSEventRunModal
-#17 0x030c30d1 GSEventRun
-#18 0x00304af2 in UIApplicationMain
-#19 0x0000242c main at main.m:14

これは、(以下のコメントも見てみると) 解放する前に何か (おそらく文字列) に対して alloc を呼び出していないことを意味していると思いますか?

4

3 に答える 3

0

ソース全体なしで特定するのは難しいですが、NSStringオブジェクトで2番目の(そして無効な)リリースを呼び出しているようです。プロジェクト全体で文字列をどのように扱っているかを見てみましょう。プロパティ宣言に「copy」属性が含まれていることと、すでに自動リリースされているものを不必要にリリースしていないことを確認してください。(つまり、[NSString stringWithFormat:]が作成されたもの)

于 2010-11-22T14:22:36.560 に答える
0

ゾンビを有効にしてアプリを実行しましたか? それはおそらくゾンビが拾うオーバーリリースです。

これを追跡する別の方法は、malloc 履歴を有効にして、不良ポインター (コメントの 0x818c0b0) がどこから来ているかを確認することです。

これはあなたに役立つかもしれません:iPhone - 「解放されているポインタが割り当てられていません」エラーのデバッグ

CFString/オブジェクト内でメモリが破損しているように見えNSStringます。これは、まったく無関係に見える場所で発生している可能性があることを意味します。に不正なポインターを渡している可能性があるNSStringため、それも確認することをお勧めします。

また、 の値はmDataReaderSelector何ですか? a を実行しperformSelector:、メソッドが構造体 (NSRect など) を返すと、メモリが破損する可能性があります。遠い話ですが、とにかくチェックしてみようと思いました。

于 2010-11-22T13:49:19.247 に答える
0

Zombie を有効にした後に修正されました (これは、追跡されたリークのみであり、二重の解放/自動解放ではないと考えていました)。必要のない文字列を自動解放していました。

TomDalling と drowntoge のおかげで、あなたはどちらも正しい軌道に乗っていました。私はちょうどそこに着き、あなたの答えを見ました(私がこれを投稿していたので)とにかくすぐに私をそこに連れて行ったでしょう. stringWithFormat が自動解放され、とにかく自動解放されていることに気づきませんでした。本当に自動リリースの使用を開始したばかりで、ローカルに割り当てて、保持されたプロパティにそのローカルを割り当てた後にそれらを解放していました。これは、コードがそれほど整頓されていないだけでも問題ありません。気が付かないうちに、たくさんのリークがあったと思います。しばらく前にメモリに関するドキュメントを読んだことがありますが、自動解放を使用したことがないので、もう一度それらに戻る必要があると思います:-)

2番目の接続はしばらくしてから有効になっているため、最初の接続が有効になっているときに問題がどのように発生したかはまだわかりません。つながりを理解することがすべてだと思っていたので、完全に私を投げました。ただし、問題の文字列はこのコード内とその周辺にありました。うーん、とにかく乾杯。

于 2010-11-22T15:08:26.157 に答える