2012-05-07 13 views
0

次のコードがあります。このプロパティのiVarは、クラスdeallocのメソッドで保持され解放されています。 iVarは2つのメソッドで使用され、値を連続的に変更しますが、値が壊れている場合は を使用することがあります。何故ですか?@propertyのメモリの破損

.H

@interface ChatController : NSObject <ASIHTTPRequestDelegate>{ 
NSTimer *timer; 
NSString *_idLastMessageFromServer; 
} 

@property(nonatomic, retain)NSString *idLastMessageFromServer; 
@end 

.M

@implementation ChatController 

@synthesize idLastMessageFromServer = _idLastMessageFromServer; 

- (void)initLoopTimer{ 
timer = [NSTimer timerWithTimeInterval:5 target:self selector:@selector(update:) userInfo:nil repeats:YES]; 
[[NSRunLoop mainRunLoop] addTimer:timer forMode:NSDefaultRunLoopMode]; 
} 

- (void)update:(id)sender{ 
ASIFormDataRequest *request = [ASIFormDataRequest requestWithURL:CONSTANT_YYYY]; 
[request setDelegate:self]; 
[request addPostValue:_idLastMessageFromServer forKey:CONSTANT_XXX]; 
[request setDidFinishSelector:@selector(requestUpdateFinish:)]; 
[request startAsynchronous]; 
} 

- (void)requestUpdateFinish:(ASIHTTPRequest *)request{ 
NSString *response = [request responseString]; 
if(response && response.length){ 
    if(![response isEqualToString:CHAT_RESPONSE_NO_MESSAGES]){ 
     NSArray *array = [response componentsSeparatedByString:CHAT_PARSE_RESPONSE]; 
     if(array && [array count] == 2){ 
      **_idLastMessageFromServer = [array objectAtIndex:0];** 
     } 
    } 
    } 
} 

しかし、ループ方法更新呼び出すとき:を、それがEXC_BAD_ACCESSとコード

[request addPostValue:_idLastMessageFromServer forKey:CONSTANT_XXX]; 

のこの行にクラッシュメッセージ、なぜですか?

+0

メモリ破損を検索するときに役立つように、タイトルのスペルを修正する必要があります。 – Cthutu

+0

ありがとう@ジャッキーボーイ – NTTake

答えて

3

self.idLastMessageFromServerの代わりに_idLastMessageFromServerを使用すると、文字列は保持されません。これは、オブジェクトの割り当てを解除する保持カウントをゼロにすることを可能にします。その時点であなたは悪いメモリへの参照を持っているので、アプリケーションがクラッシュします。

正当な理由がない限り、iVarsは直接使用しないでください(-initや-deallocなど)。代わりにプロパティを使用してください。

[request addPostValue:self.idLastMessageFromServer forKey:CONSTANT_XXX]; 

self.idLastMessageFromServer = [array objectAtIndex:0]; 

私は、プロパティについての詳細な説明の少しを追加します。

self.idLastMessageFromServerプロパティの値の読み取りに使用すると、自動生成されたメソッド-idLastMessageFromServerが呼び出されます。プロパティの値が自動生成されたメソッド-setIdLastMessageFromServer:を呼び出して設定するために使用された場合

- (NSString *)idLastMessageFromServer 
{ 
    return _idLastMessageFromServer; 
} 

self.idLastMessageFromServer:このメソッドは次のようになります。

- (void)setIdLastMessageFromServer:(NSString *)idLastMessageFromServer 
{ 
    if (_idLastMessageFromServer != idLastMessageFromServer) { 
     [_idLastMessageFromServer release]; 
     _idLastMessageFromServer = idLastMessageFromServer; 
     [_idLastMessageFromServer retain]; 
    } 
} 

最後の注意:このメソッドは次のようになりますあなたの-dealloc方法で_idLastMessageFromServerを解放するようにしてください。ような何か:プロパティとアイバーズについて

- (void)dealloc 
{ 
    [_idLastMessageFromServer release]; 
    [super dealloc]; 
} 

詳細。

プロパティ(selfのように。idLastMessageFromServer)は、getterメソッドとsetterメソッドを処理する簡単な方法です。それらはメソッドであるため、データを保持することはできません。 iVars(_idLastMessageFromServerなど)は、メモリ内の場所へのポインタです。単純なポインタなので、アクセスを制御したり状態を維持することはできません。

プロパティとiVarsが連携します。

@property(nonatomic, retain) NSString *idLastMessageFromServer;は私の実装のどこかで、私のクラスはプロパティidLastMessageFromServerのゲッターとセッターを持っていると言います。

@synthesize idLastMessageFromServer = _idLastMessageFromServer;は、iVar _idLastMessageFromServerを使用して、idLastMessageFromServerのgetterおよびsetterメソッドを自動的に生成します。

つまり、プロパティはiVarへのアクセスを制御します。 iVarはプロパティの格納場所です。

+0

今私はそれを試してみるつもりですが、私はあなたが@ idLastMessageFromServer = _idLastMessageFromServerを合成するので、あなたの理由はなぜですか? _idLastMessageFromServerはself.idLastMessageFromServerと同じかどうか? – NTTake

+0

いいえ、そうではありません。 _idLastMessageFromServerは変数です。 self.idLastMessageFromServerは、-idLastMessageFromServerまたは-setIdLastMessageFromServerへのメソッド呼び出しです([宣言されたプロパティ](https://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/ObjectiveC/Chapters/ocProperties.htmlを参照)。 )) –

+0

ありがとう@Jefferyトーマスしかし、なぜ使用する_idLastMessageFromServerのためのdiferenteがある場合、なぜプロパティ(self.idLastMessage)だけが使用される場合iVarを作成する必要があります。 NSString * idLastMessageFromServer; '@property(nonatomic、retain)NSString * idLastMessageFromServer;を宣言するだけでなく、iVarを使用しないので、' NSString * _idLastMessageFromServer; 'と' @synthesize idLastMessageFromServer = _idLastMessageFromServer; _idLastMessageFromServer'。 – NTTake

5

このライン:

_idLastMessageFromServer = [array objectAtIndex:0]; 

は、おそらくこれは、このように割り当て中に保持/解放をトリガー、直接施設の代わりに、変数にアクセスする

self.idLastMessageFromServer = [array objectAtIndex:0]; 

でなければなりません。それ以外の場合、ポインタは割り当てられますが、配列から取り出されたオブジェクトは保持されません。すぐに無効になり、解放されたオブジェクトを指すポインターが残ります。

+0

今私はそれを試してみるつもりですが、もしあなたが私が@ synthesize idLastMessageFromServer = _idLastMessageFromServer; _idLastMessageFromServerはself.idLastMessageFromServerと同じかどうか? – NTTake

+0

いいえ、同じではありません。 _idLastMessageFromServerは実際のポインタであり、self.idLastMessageFromServerは保持を行うコードの構文的な砂糖です。私はそれが 'if(nil!= _x){[_x release]; } _x = newValue; [_x retain]; ' – craigmj

+0

@craigmjに感謝しますが、なぜ、_idLastMessageFromServerを使用するのかが異なる場合は、プロパティのみを使用する場合はなぜiVarを作成する必要があります(self.idLastMessage)。 – NTTake

関連する問題