在Blocks中发布委托不起作用(ASIHTTPRequest)

时间:2012-06-20 01:50:48

标签: iphone objective-c delegates asihttprequest block

我在使用Blocks内的委托时遇到问题。

启用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];
}

似乎我无法在Blocks中发布委托。 在这种情况下我该怎么办?

我可以使用通知,但我觉得这不是一个好方法。

这是班级的主要部分。 如果我不使用弱,请求部分将进行保留循环,因此不确定该做什么。

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


@implementation URLFilter
@synthesize delegate    = delegate_;

*的解决!!!

它通过制作另一个__block id blockDelegate来工作。 而且,也没有内存泄漏。

- (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];
}

更新

我再次查看了代码,问题可能是由这个块方法引起的 那是什么方法。

在这个twitter api块方法的内部,我称之为whatsGoingOn方法,并且在whatsGoingOn方法中,我放了asihttprequest块方法。

奇怪的是,如果我在块的一侧使用asihtttprequest的常用委托方法,它会粉碎, 这就是为什么我选择了asihttprequest的块方法。

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

3 个答案:

答案 0 :(得分: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];
}

答案 1 :(得分:2)

从不依靠弱引用。假设请求是在代码中的方法内创建的,它将在下一行甚至运行之前立即释放。

通过更新,我看到了参考周期。你应该做的是让request成为iVar。然后在块之前执行此操作:

ASIHTTPRequest __weak *weakRequest = mRequest;

然后参考弱请求而不是强请求。

答案 2 :(得分:1)

它通过制作另一个__block id blockDelegate来工作。 而且,也没有内存泄漏。 :)

//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];