【问题标题】:When will a local variable be killed when it holds the delegate references?当一个局部变量持有委托引用时,它什么时候会被杀死?
【发布时间】:2012-12-30 07:15:54
【问题描述】:

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

在控制器中,如果它拥有该对象。我们应该为它分配一个强指针。 这样它拥有的对象就不会丢失。

我创建了一个小型库类来帮助我进行异步连接,它拥有一个指向采用其协议的 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];   
}

我尝试了两次记录连接对象的内存地址,它们是不同的。 (我按了两次按钮)。所以我想知道连接对象什么时候会被杀死。

【问题讨论】:

    标签: objective-c ios delegates


    【解决方案1】:

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

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

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

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

    【讨论】:

    • 它只做_delegate = delegate;。我尝试了您的建议,即将deadlloc 添加到课程中。结果令人惊讶。该对象将在 NSURLConnection 的委托方法之后被释放。我将编辑我的问题:)
    • 第一个答案打勾:)
    【解决方案2】:

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

    特别注意事项

    在下载期间,连接保持对委托的强引用。当连接完成加载、失败或被取消时,它会释放该强引用。

    所以有一个小型(有意的)保留周期来保持您的 AsycConnection 对象处于活动状态。

    【讨论】:

    • 你的猜测是对的 :) 它将创建一个 NSURLConnection。在末尾。 NSURLConnection 释放 AsycConnection 对象。这就是为什么我发现当连接完成加载时我的 AsycConnection 对象将被释放。 :)
    • 那么,您还有什么需要了解的吗,或者让 Kurt 和我回答了您的问题?
    • 你的回答也很棒:)
    • 库尔特的更好,我的只是填补了空白。
    猜你喜欢
    • 1970-01-01
    • 2023-03-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-16
    • 2011-06-09
    • 1970-01-01
    • 2016-11-21
    相关资源
    最近更新 更多