iOSが画面破壊時にどのように優雅なcancelネットワークを要求しますか?


前言
皆さんはご存知のように、ネットでお願いした後、もし無視しなければ、次のような状況が発生する可能性があります。
あるページに入ると、ある操作(ページから退出したり、あるタブを切り替えるなど)をして、以前の要求が無駄になり、ページが破壊されましたが、ネット上の要求がまだ外に飛んでいる場合があります。放置しておくと、この要求は流量を浪費したり、性能を浪費したりします。タイムアウトの無駄なお願いはもっと不愉快です。この時、私達の一番いい方法はcancelがこれらの無駄な要求を落とすことです。
伝統的なキャンセル方式はこうです。
1.クラスには要求対象を持つ必要があります。

@property (strong/weak, nonatomic) XXRequest *xxrequest1; 
具体的にはstrongを使うかweakを使うかはネットワーク層の設計によって決まります。一部のネットワーク層のrequestは完全な臨時変数です。方法を出したら直接廃棄する必要があるのはstrongです。一部のデザインは自分の持っている特性を持っています。
2.請求の場所において、請求の値を付与する。

xxrequest1 = xxx;
self.xxrequest1 = xxrequest1;
[xxrequest1 start];
3.廃棄が必要なところでは、通常本類のdeallocの中にあります。

[self.xxrequest1 cancel];
cancelのためにrequestを見られます。私たちの要求対象はどこにでもあります。もういくつかお願いがあれば、もっと気持ちが悪くなります。
どのような方法が私たちを楽にさせることができますか?
ターゲット:
私達は一部の要求を制御することができることを望んで、ページで廃棄して、managerが釈放するなどの時機、自動的なcancelは私達の出した要求を落として、私達が手動で上のこのような至る所すべてのコードを書く必要はありません。
シナリオ:
傍受類のdeallocメソッド呼び出しは、deallocが実行されると、requestのcancel方法が実行されます。
すぐに問題を発見しました。
ARCでは、ヤフークラスのdealloc方法は許されないので、ヤフーはだめです。他の方法がありますが、クラスがdeallocされていることを知ることができますか?
実際にはいくつかの変更案を採用して得ることができます。私たちはassicatedバインディングの属性を知っています。バインディング時の設定によって、deallocで自動的にリリースできるので、この点を利用して、モニターのdealloc呼び出しを行うことができます。
  • は、deallocを実行する際に要求されたキャンセル方法
  • を実行する中間クラスAを構築する。
  • は、assicateによって結合され、廃棄類を任意の実行クラスBに結合する
  • このようにして、クラスBの破壊を実行する時、内部のassicateの属性を破壊する時、私達は相応する実行の機会を得ることができます。
  • コアコードを以下に示します。
    キャンセル要求のクラスを作成します。
    
    @interface YRWeakRequest : NSObject
    @property (weak, nonatomic) id request;
    @end
    @implementation YRWeakRequest
    @end
    2.ある種のバインディングのすべての要求を記録するためのクラスを構築する
    
    @interface YRDeallocRequests : NSObject
    @property (strong, nonatomic) NSMutableArray<YRWeakRequest*> *weakRequests;
    @property (strong, nonatomic) NSLock *lock;
    @end
    @implementation YRDeallocRequests
    - (instancetype)init{
     if (self = [super init]) {
     _weakRequests = [NSMutableArray arrayWithCapacity:20];
     _lock = [[NSLock alloc]init];
     }
     return self;
    }
    - (void)addRequest:(YRWeakRequest*)request{
     if (!request||!request.request) {
     return;
     }
     [_lock lock];
     [self.weakRequests addObject:request];
     [_lock unlock];
    }
    - (void)clearDeallocRequest{
     [_lock lock];
     NSInteger count = self.weakRequests.count;
     for (NSInteger i=count-1; i>0; i--) {
     YRWeakRequest *weakRequest = self.weakRequests[i];
     if (!weakRequest.request) {
      [self.weakRequests removeObject:weakRequest];
     }
     }
     [_lock unlock];
    }
    - (void)dealloc{
     for (YRWeakRequest *weakRequest in _weakRequests) {
     [weakRequest.request cancel];
     }
    }
    @end
    3.任意のクラスにこの中間クラスをバインドする
    
    @implementation NSObject (YRRequest)
    
    - (YRDeallocRequests *)deallocRequests{
     YRDeallocRequests *requests = objc_getAssociatedObject(self, _cmd);
     if (!requests) {
     requests = [[YRDeallocRequests alloc]init];
     objc_setAssociatedObject(self, _cmd, requests, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
     }
     return requests;
    }
    
    - (void)autoCancelRequestOnDealloc:(id)request{
     [[self deallocRequests] clearDeallocRequest];
     YRWeakRequest *weakRequest = [[YRWeakRequest alloc] init];
     weakRequest.request = request;
     [[self deallocRequests] addRequest:weakRequest];
    }
    @end
    4.対外暴露のヘッダファイル
    
    @interface NSObject (YRRequest)
    /*!
     * @brief add request to auto cancel when obj dealloc
     * @note will call request's cancel method , so the request must have cancel method..
     */
    - (void)autoCancelRequestOnDealloc:(id)request;
    @end
    使い方
    どうですか?最初の書類を見るのは簡単だと思いますか?使い方は簡単です。
    例えば、私達はあるVCにいる必要があります。リリース時に自動キャンセルネットワークで要求します。
    
    //       :
    xxrequest1 = xxx;
    [xxrequest1 start];
    [self autoCancelRequestOnDealloc:xxrequest1];
    はい、これからはこの類の廃棄が心配されなくなりました。
    その他:
    1.私の実現クラスでは、デフォルトで呼び出されたのはcancel方法ですので、理論的には、cancelの方法があるすべてのrequestは直接にこの方法で呼び出すことができます(AFNetworking、NSURLSessionTaskなど)。
    2.一部の人は、自分のネットワーク層を使って、自分でパッケージ化したrequsetからの要求で、キャンセルを呼び出さないと、自分でパッケージ化したオブジェクトも廃棄されると言います。注意したいのは、自分でカプセル化した対象が廃棄された可能性がありますが、その下の階には、ドッキングがAFであってもシステムであっても、あるいは他の要求庫であっても、必ず自前の性質があります。
    3.例で私が縛っているのはselfですが、実際にはどのようなオブジェクトにも結びつけることができます。例えば、ある種類の内部属性など、業務ニーズに応じて要求のcancelタイミングをさらに制御できます。
    githubの住所を添付します。ご指摘を歓迎します。https://github.com/YueRuo/NSObject_AutoCacel Request。 ( ローカルダウンロード
    締め括りをつける
    以上はこの文章の全部の内容です。本文の内容は皆さんの学習や仕事に対して一定の参考となる学習価値を持っています。質問があれば、メッセージを書いて交流してください。ありがとうございます。