0

デリゲート パターンのメモリ管理がよくわかりません。

コントローラーで、そのオブジェクトを所有している場合。それに強いポインタを割り当てる必要があります。それが所有するオブジェクトが失われないように。

非同期接続を行うのに役立つ小さなライブラリ クラスを作成しました。これは、そのプロトコルを採用する ViewController への弱いポインタを保持します。接続が完了すると、データが ViewController に返されます。

#import <Foundation/Foundation.h>

@protocol AsyncConnectionDelegate;

@interface AsyncConnection : NSObject <NSURLConnectionDataDelegate>
@property (weak, nonatomic) id <AsyncConnectionDelegate> delegate;

-(void)callAsyncConnectionAtUrl:(NSString *)url dictionary:(NSDictionary *)dictionary method:(NSString *)method delegate:(id)delegate;
@end

@protocol AsyncConnectionDelegate <NSObject>
- (void)finishConnectionWithData:(NSData *)data connection:(AsyncConnection *)connection;
@end

使用法: (ボタンが押されたとき)

// user input
NSString *username = _usernameTextField.text;
NSString *password = _pwdTextField.text;

//create dictionary key-value pair for transformming into NSData
NSMutableDictionary *loginKeyValue = [[NSMutableDictionary alloc]init];
[loginKeyValue setObject:username forKey:@"username"];
[loginKeyValue setObject:password forKey:@"password"];


AsyncConnection *conc = [[AsyncConnection alloc]init];
[conc callAsyncConnectionAtUrl:@"http://localhost:3000/login.json" dictionary:loginKeyValue method:@"POST" delegate:self];

これ*concはローカル変数のみであり、View Controllerはそれへの強い参照を保持していませんでした。したがって、私の観点では、メソッドの実行が終了したときに強制終了されるはずです。ただし、それは生きていて、ViewController にデータを送り返すことができます。

委任方法

- (void)finishConnectionWithData:(NSData *)data connection:(AsyncConnection *)connection{

    NSLog(@"Connection Object : %@", connection );

    Member *member = [Member initWithData:data];
    NSLog(@"member username \n %@",member.username);
    NSLog(@"member password \n %@",member.password);

    NSString *msg = (member.username)?@"Login Success":@"Failed to login";

    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"NOTICE!!" message:msg delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil];
    [alert show];
}

クラスはこのメソッドを使用してデータを送り返します。これは NSURLConnection のデリゲート メソッドです。

- (void)connectionDidFinishLoading:(NSURLConnection *)connection{
    [_delegate finishConnectionWithData:_downloadData connection:self];   
}

接続オブジェクトのメモリ アドレスを 2 回記録しようとしましたが、それらは異なります。(ボタンを2回蹴った) . だから、接続オブジェクトがいつ殺されるのだろうか。

4

2 に答える 2

3

動作は の実装によって異なります-[AsyncConnection callAsyncConnectionAtUrl:dictionary:method:delegate:]

それがまったく何もしなかった場合、あなたは正しいですAsyncConnection *conc。他の誰もそれを保持しないため、ボタンが押されたメソッドの最後に割り当てが解除されると予想されます。

ただし、おそらくしばらく保持される-callAsyncConnectionAtUrl:原因となる何かを行います。self(それをself保持する可能性のある他のコードに渡されますか?または、を参照するブロックが含まれておりself、そのブロックを他のコードに渡しますか?)

AsyncConnectionが実際に割り当て解除されるタイミングを知りたい場合は、簡単に見つけることができます。 dealloctoの実装を追加しAsyncConnection、そこにブレークポイントを設定して、コードを実行します。

于 2012-12-30T07:30:13.623 に答える
1

オブジェクトの名前から、おそらく NSURLConnection を作成し、自身をデリゲートとして設定します。NSURLConnection のドキュメントから:

特別な考慮事項

ダウンロード中、接続はデリゲートへの強力な参照を維持します。接続の読み込みが完了するか、失敗するか、またはキャンセルされると、その強い参照が解放されます。

したがって、AsycConnection オブジェクトを維持するミニ (意図的な) 保持サイクルがあります。

于 2012-12-30T08:11:55.083 に答える