2

iOS4 でアプリを実行すると、奇妙な EXC_BAD_ACCESS エラーが発生します。このアプリは、しばらくの間 OS3.x でかなり安定しており、実際にはコードのこの領域 (または多くの領域) でクラッシュ ログを確認することさえありませんでした。

このコードまでエラーを追跡しました:

メインクラス:

- (void) sendPost:(PostRequest*)request {
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

    NSURLResponse* response;
    NSError* error;
    NSData *serverReply = [NSURLConnection sendSynchronousRequest:request.request returningResponse:&response error:&error];

    ServerResponse* serverResponse=[[ServerResponse alloc] initWithResponse:response error:error data:serverReply]; 

    [request.objectToNotifyWhenDone performSelectorOnMainThread:request.targetToNotifyWhenDone withObject:serverResponse waitUntilDone:YES];

    [pool drain];
}

(注: sendPost は、呼び出しごとに別のスレッドで実行されます。PostRequest は、リクエストをカプセル化するクラスと、完了時に通知するセレクターです)

ServerResponse.m:

@synthesize response;
@synthesize replyString;
@synthesize error;
@synthesize plist;

- (ServerResponse*) initWithResponse:(NSURLResponse*)resp error:(NSError*)err data:(NSData*)serverReply {
    self.response=resp;
    self.error=err;
    self.plist=nil;
    self.replyString=nil;

    if (serverReply) {
        self.replyString = [[[NSString alloc] initWithBytes:[serverReply bytes] length:[serverReply length] encoding: NSASCIIStringEncoding] autorelease];
        NSPropertyListFormat format;
        NSString *errorStr;
        plist = [NSPropertyListSerialization propertyListFromData:serverReply mutabilityOption:NSPropertyListImmutable format:&format errorDescription:&errorStr];
    }

    return self;
}

ServerResponse.h:

@property (nonatomic, retain) NSURLResponse* response;
@property (nonatomic, retain) NSString* replyString;
@property (nonatomic, retain) NSError* error;
@property (nonatomic, retain) NSDictionary* plist;

- (ServerResponse*) initWithResponse:(NSURLResponse*)response error:(NSError*)error data:(NSData*)serverReply;

これは、次の行の不正なアクセスで確実にクラッシュします。

self.error=err;

...つまり、合成されたプロパティ セッターで!

コードが以前のOSで機能し、それ以来変更されていないことを考えると(以前のSDKでコンパイルされたバイナリでさえ同じようにクラッシュしますが、OS3.0ではクラッシュしません)-そしてそれを考えると、なぜこれが必要なのかについて困惑しています単純なプロパティ メソッドです。

何か案は?リリース間で NSError の実装が変更された可能性がありますか、それとも明らかな何かが欠けていますか?

4

2 に答える 2

3

セッターは、新しい値に対して [retain] を呼び出し、古い値に対して [release] を呼び出します。不正なアクセスを引き起こすには、そのうちの 1 つが無効 (かつ非 nil) でなければなりません。

sendPost はローカル エラー変数を初期化しません。NSURLConnection によって設定されていない場合は、ガベージが含まれます。sendPost でエラーを nil に初期化してみてください。

于 2010-06-10T00:03:25.970 に答える
1

sendPost: メッセージで serverResponse を解放したことがありますか?

init がその親の init を呼び出すことはありません。次のようなものを試してください:

- (ServerResponse*) initWithResponse:(NSURLResponse*)resp error:(NSError*)err data:(NSData*)serverReply
{   
    if (self = [super init])
    {
        // ....
    }
    return self;
}
于 2010-06-10T00:26:36.343 に答える