注:This similar SO questionは、同じクラスを構築する方法について話しますが、クラスの使用に関連するメモリ管理の問題には対処しません。カスタムNSURLConnectionラッパーオブジェクトの所有権を保持する必要はありますか? (ARC環境で)
私はsendAsynchronousRequest:queue:completionHandler:
を使用したいと思いますが、iOS 4.2をサポートする必要があります。
- :私は(私はARCのメモリ管理にいるよ)このクラスの使用方法について質問があり
- (void)sendRequest:(NSURLRequest *)request responseHandler:(JCURLResponseHandler)responseHandler;
:したがって、私は
NSURLConnection
を使用して、素敵なインターフェイスを生成JCURLRequest
というカスタムクラスを作成しました私は自分のJCURLRequestオブジェクトを作成しますが、そのオブジェクトへの参照を保持する必要がありますか?それとも、「火をつけて忘れることはできますか?
注:オブジェクトへのポインタがある場合、オブジェクトへのポインタがない場合は、次の自動リリースで解放されます。プール。
このように、私が知りたい - 私は同じようにそれを呼び出すことができます(1)またはI(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)を使用する必要があると考えています。これは、デリゲートコールバックがコールバックするまでに、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について知りませんでした - ありがとう、それはとても役に立ちます。私はそれが[特別な考慮事項](http://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Classes/NSURLConnection_Class/Reference/Reference.html#//apple_ref/doc/uid/)で見つかりました。 20001697-BAJDDIDG)これについての公式の文書が表示されます。 '__unused'については、' Expression result unused'という警告を抑制するために使用します。あなたはその警告を抑制する別の方法を知っていますか? – bearMountain
また、ブロック内で 'self'を参照すると、ブロックは保持されます。 – Joe
@bearMountain警告を抑制する別の方法は、式の結果を保存しないことです! (私が上に示したように)。変数を使用しない場合は、変数を格納する必要はありません。 – joerick