gpt4 book ai didi

objective-c - 我是否需要保留自定义 NSURLConnection 包装器对象的所有权? (在 ARC 环境中)

转载 作者:行者123 更新时间:2023-12-04 18:22:56 27 4
gpt4 key购买 nike

注:This similar SO question谈论如何构建相同的类,但没有解决与使用该类相关的内存管理问题。

我想使用 sendAsynchronousRequest:queue:completionHandler: ,但是我需要支持 iOS 4.2。因此,我创建了一个名为 JCURLRequest 的自定义类。使用 NSURLConnection并生成一个漂亮的界面:

- (void)sendRequest:(NSURLRequest *)request 
responseHandler:(JCURLResponseHandler)responseHandler;

我有一个关于使用这个类的问题(我在 ARC 内存管理中):
  • 当我创建我的 JCURLRequest 对象时,我需要保留对该对象的引用吗?还是我可以“开火然后忘记它”?

  • 注意:我了解 ARC 的基础知识 - 如果您有一个指向对象的指针,它将保持事件状态,如果没有更多指向对象的指针,它将在下一个自动释放池中释放。

    因此,我想知道 - 我可以像(1)那样称呼它还是我需要使用(2)

    (1)
    JCURLRequest *jcURLRequest = [[JCURLRequest alloc] init];
    [jcURLRequest sendRequest:myRequest
    responseHandler:^(NSData *data, NSError *error) { ... }];
    // Assuming I don't maintain a reference to jcURLRequest after this

    (2)
    // Assume @property (strong) JCURLRequest *jcURLRequest;
    // @synthesize jcURLRequest = _jcURLRequest;
    self.jcURLRequest = [[JCURLRequest alloc] init];
    [self.jcURLRequest sendRequest:myRequest
    responseHandler:^(NSData *data, NSError *error) { ... }];
    NSURLConnection使用异步回调,所以我的想法是我必须使用(2)。这是因为 - 当委托(delegate)回调“回调”时,jcURLRequest 实例可能已经在自动释放池中被清理了。

    不过我很困惑,因为我已经用 (1) 进行了测试,它“似乎”工作正常。但是,我的想法是,它的工作可能只是巧合 - 即。确实没有更多有效的指向 jcURLRequest 对象的指针,但 iOS 还没有解决它。

    以下是完整的 JCURLRequest引用类
    //  JCURLRequest.h
    #import <Foundation/Foundation.h>

    typedef void (^JCURLResponseHandler) (NSData *data, NSError *error);

    @interface JCURLRequest : NSObject
    - (void)sendRequest:(NSURLRequest *)request responseHandler:(JCURLResponseHandler)responseHandler;
    @end



    // JCURLRequest.m
    #import "JCURLRequest.h"

    @interface JCURLRequest ()
    {
    JCURLResponseHandler responseHandler;
    }
    @property (strong, nonatomic) NSMutableData *responseData;
    @end

    @implementation JCURLRequest
    @synthesize responseData = _responseData;


    #pragma mark - Public API

    - (void)sendRequest:(NSURLRequest *)request responseHandler:(JCURLResponseHandler)handler
    {
    responseHandler = [handler copy];
    dispatch_async(dispatch_get_main_queue(), ^{
    __unused NSURLConnection *connectionNotNeeded = [[NSURLConnection alloc] initWithRequest:request delegate:self];
    });
    }


    #pragma mark - Private API

    - (NSMutableData *)responseData
    {
    if (!_responseData)
    {
    _responseData = _responseData = [[NSMutableData alloc] initWithLength:0];
    }

    return _responseData;
    }


    #pragma mark - URL Connection Methods

    - (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
    {
    [self.responseData setLength:0];
    }

    - (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
    {
    [self.responseData appendData:data];
    }

    - (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
    {
    responseHandler(nil, error);
    }

    - (void)connectionDidFinishLoading:(NSURLConnection *)connection
    {
    responseHandler([NSData dataWithData:self.responseData], nil);
    }

    @end

    最佳答案

    NSURLConnection 在连接处于事件状态时保留它的委托(delegate),以及它自己。因此,您的解决方案有效并非巧合。

    我找不到任何官方消息来源,但已在 SO 上非正式地确认:

  • been having a little confusion about the retainCount of NSURLConnection
  • Does a NSURLConnection retain its delegate?
  • 关于objective-c - 我是否需要保留自定义 NSURLConnection 包装器对象的所有权? (在 ARC 环境中),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10287222/

    27 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com