当局部变量保存委托引用时何时会被杀死?

时间:2012-12-30 07:15:55

标签: objective-c ios delegates

我真的不了解委托模式中的内存管理。

在Controller中,如果拥有该对象。我们应该为它指定一个强大的指针。 因此拥有的对象不会丢失。

我创建了一个小型库来帮助我进行异步连接,它拥有一个指向采用其协议的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这里只是一个局部变量,视图控制器没有强大的引用。所以在我看来,它应该在方法执行完毕时被杀死。但是,它可以存活并将数据发送回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 个答案:

答案 0 :(得分:3)

行为取决于-[AsyncConnection callAsyncConnectionAtUrl:dictionary:method:delegate:]的实施。

如果它什么也没做,那么你是对的,你会期望在按下按钮的方法结束时释放AsyncConnection *conc,因为没有其他人会保留它。

但是,-callAsyncConnectionAtUrl:可能会导致self保留一段时间。 (它是否将self传递给可能保留它的其他代码?或者它是否包含引用self的块,然后将该块传递给其他代码?)

如果你想知道AsyncConnection何时在实践中被解除分配,很容易找到:将dealloc的实现添加到AsyncConnection,在其中设置断点,然后运行你的代码。

答案 1 :(得分:1)

通过对象的名称,它可能会创建一个NSURLConnection并将自身设置为委托。来自NSURLConnection的文档:

  

特别注意事项

     

在下载过程中,连接会保留对委托的强引用。当连接完成加载,失败或被取消时,它会释放强引用。

所以有一个迷你(有意)的保留周期让你的AsycConnection对象保持活着状态。