1

ブロック内でデリゲートを使用する際に問題が発生しました。

ARCがオンの場合、これは問題を示す例です。

- (void)whatsGoingOn {

    NSString *address = @"someAddress";    

    //setting for request
    NSURL *requestURL               = [NSURL URLWithString:address];    
    __weak ASIHTTPRequest *request  = [ASIHTTPRequest requestWithURL:requestURL];    

    [delegate_ postDelegateMethod]; //This delegation works fine       

    [request setCompletionBlock:^{     
        [delegate_ postDelegateMethod]; //This delegation doesn't work        
    }];

    [request startAsynchronous];
}

ブロック内に委任を投稿できないようです。この状況で私は何をすべきですか?

代わりに通知を使用することもできますが、それが良い方法だとは思いません。

これはクラスの頭の部分です。ウィークを使用しない場合、リクエスト部分は保持サイクルを作成するため、まだ何をすべきかわかりません。

@interface URLFilter : NSObject {
      id __weak                   delegate_;
}
@property (nonatomic, weak) id                              delegate;


@implementation URLFilter
@synthesize delegate    = delegate_;

*解決しました!!!

別の__blockidblockDelegateを作成することで機能しました。また、メモリリークもありません。

- (void)whatsGoingOn {

    NSString *address = @"someAddress";    

    //setting for request
    NSURL *requestURL               = [NSURL URLWithString:bitlyAPIAddress];    
    __weak ASIHTTPRequest *request  = [ASIHTTPRequest requestWithURL:requestURL];    

    //set blockDelegate since delegate_ will be gone inside blocks
    __block id blockDelegate        = delegate_;

    [request setCompletionBlock:^{        

        //it works
        [blockDelegate postDelegateMethod];
    }];

    [request startAsynchronous];
}

アップデート

コードをもう一度確認しましたが、この問題は、whatsGoingOnメソッド以外のこのブロックメソッドが原因である可能性があります。

このTwitterAPIブロックメソッド内にwhatsGoingOnメソッドを呼び出し、whatsGoingOnメソッド内にasihttprequestブロックメソッドを配置します。

不思議なことに、ブロックの横でasihtttprequestの通常のデリゲートメソッドを使用すると、クラッシュするため、asihttprequestのブロックメソッドを選択しました。

//request tweet data
[twRequest performRequestWithHandler:^(NSData *responseData,
                                         NSHTTPURLResponse *urlResponse,
                                         NSError *error) {
    [self whatsGoingOn];                            
}];
4

3 に答える 3

3

問題がリクエストの__weak修飾子であることを確認してください。私が正しければ、ブロック内でデリゲート呼び出しを取得することはなく、他に何も取得することはありません。リクエストのブロックのコピーは、実行される前にクリーンアップされます。

- (void)whatsGoingOn {

    NSString *address = @"someAddress";    

    //setting for request
    NSURL *requestURL        = [NSURL URLWithString:address];    
    ASIHTTPRequest *request  = [ASIHTTPRequest requestWithURL:requestURL];    

    [request setCompletionBlock:^{
        NSLog(@"proof we got here.  delegate = %@", self.delegate);   
        [self.delegate postDelegateMethod]; // This delegation _should_ work        
    }];

    [request startAsynchronous];
}
于 2012-06-20T02:02:34.100 に答える
2

弱参照がくっついていることを決して期待しないでください。リクエストがコードのメソッド内で作成されたとすると、次の行が実行される前に、すぐに割り当てが解除されます。

更新により、参照サイクルが表示されます。あなたがすべきことはrequestiVarを作ることです。次に、ブロックの前にこれを行います。

ASIHTTPRequest __weak *weakRequest = mRequest;

次に、強い要求ではなく、弱い要求を参照します。

于 2012-06-20T02:05:55.550 に答える
1

別の__blockidblockDelegateを作成することで機能しました。また、メモリリークもありません。:)

//setting for request
NSURL *requestURL               = [NSURL URLWithString:bitlyAPIAddress];    
__weak ASIHTTPRequest *request  = [ASIHTTPRequest requestWithURL:requestURL];    

//set blockDelegate since delegate_ will be gone inside blocks
__block id blockDelegate        = delegate_;

[request setCompletionBlock:^{        

    //it works
    [blockDelegate postDelegateMethod];
}];

[request startAsynchronous];
于 2012-06-21T00:02:46.053 に答える