我在使用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];
}];
答案 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];