Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/114.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 超时NSOperationQueue中的同步服务器调用_Ios_Objective C_Cocoa Touch_Nsoperation_Nsoperationqueue - Fatal编程技术网

Ios 超时NSOperationQueue中的同步服务器调用

Ios 超时NSOperationQueue中的同步服务器调用,ios,objective-c,cocoa-touch,nsoperation,nsoperationqueue,Ios,Objective C,Cocoa Touch,Nsoperation,Nsoperationqueue,我正在使用NSOperation队列获取图像,并将它们显示在我的tableview单元格中。在图像返回之前,我将显示加载覆盖,一旦操作完成,它将通知代理,然后删除加载覆盖 现在,我想在5秒后暂停fetch操作并删除加载覆盖,但基于计时器的方法不起作用。请建议 下面是我的代码: #import "MyImageFetchOperation.h" #import "MyImageFetchController.h" #import "MyHTTPRequest.h" @interface MyIm

我正在使用NSOperation队列获取图像,并将它们显示在我的tableview单元格中。在图像返回之前,我将显示加载覆盖,一旦操作完成,它将通知代理,然后删除加载覆盖

现在,我想在5秒后暂停fetch操作并删除加载覆盖,但基于计时器的方法不起作用。请建议

下面是我的代码:

#import "MyImageFetchOperation.h"
#import "MyImageFetchController.h"
#import "MyHTTPRequest.h"

@interface MyImageFetchOperation ()

@property (nonatomic, strong) NSString *imageURL;
@property (nonatomic, weak) id <MyOperationCompletedDelegate> delegate;
@property (nonatomic, assign) BOOL isCompleted;
@property (nonatomic, weak) NSTimer *timeoutTimer;

@end

@implementation MyImageFetchOperation
@synthesize imageURL;
@synthesize delegate;
@synthesize isCompleted;

#define kMyImageFetchTimeout 5

#pragma mark -
#pragma mark Destruction

- (void)dealloc {
    self.delegate = nil;
}


- (id)initWithImageURL:(NSString *)iImageURL delegate:(id)iDelegate {
    if (self = [super init]) {
        self.imageURL = iImageURL;
        self.delegate = iDelegate;
    }
    return self;
}


- (void)main {
    self.isCompleted = NO;
    NSMutableURLRequest *aRequest = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:self.imageURL]];
    [aRequest setTimeoutInterval:kMyImageFetchTimeout];
    [aRequest setHTTPMethod:@"GET"];

    self.timeoutTimer = [NSTimer scheduledTimerWithTimeInterval:kMyImageFetchTimeout target:self selector:@selector(requestTimedOut) userInfo:nil repeats:NO];

    [NSURLConnection sendAsynchronousRequest:aRequest queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *iData, NSError *iConnectionError) {
        if (!self.isCompleted) {
            if (iConnectionError) {
                [[MyImageFetchController sharedRunnerImageFetchControllerMy] urlFailed:self.imageURL];
            }

            UIImage *anImage = [UIImage imageWithData:iData];

            if (anImage) {
                [MyUtilities cacheFile:anImage withName:[self.imageURL runnerMD5HashMy] toDirectory:[self.delegate cacheDirectoryForImages]];
            } else {
                [[MyImageFetchController sharedRunnerImageFetchControllerMy] urlFailed:self.imageURL];
            }

            [self.delegate operationCompletedForURL:self.imageURL];
            self.isCompleted = YES;
        }
    }];
}


- (void)requestTimedOut {
    self.isCompleted = YES;
    [self.timeoutTimer invalidate];
    self.timeoutTimer = nil;
    [[MyImageFetchController sharedRunnerImageFetchControllerMy] urlFailed:self.imageURL];
    [self.delegate operationCompletedForURL:self.imageURL];
}

@end
#导入“MyImageFetchOperation.h”
#导入“MyImageFetchController.h”
#导入“MyHTTPRequest.h”
@接口MyImageFetchOperation()
@属性(非原子,强)NSString*imageURL;
@属性(非原子,弱)id委托;
@属性(非原子,赋值)布尔完成;
@属性(非原子,弱)NSTimer*timeoutTimer;
@结束
@MyImageFetch操作的实现
@合成图像URL;
@综合代表;
@合成完成;
#定义kMyImageFetchTimeout 5
#布拉格标记-
#布拉格标记销毁
-(无效)解除锁定{
self.delegate=nil;
}
-(id)initWithImageURL:(NSString*)iImageURL委托:(id)iDelegate{
if(self=[super init]){
self.imageURL=iImageURL;
self.delegate=iDelegate;
}
回归自我;
}
-(无效)主要{
self.isCompleted=否;
NSMutableURLRequest*aRequest=[NSMutableUrlRequestWithURL:[NSURL URLWithString:self.imageURL]];
[aRequest setTimeoutInterval:kMyImageFetchTimeout];
[aRequest setHTTPMethod:@“获取”];
self.timeoutTimer=[NSTimer scheduledTimerWithTimeInterval:kMyImageFetchTimeout目标:self选择器:@selector(requestTimedOut)userInfo:nil repeats:NO];
[NSURLConnection sendAsynchronousRequest:aRequest队列:[NSOperationQueue mainQueue]完成处理程序:^(NSURResponse*response,NSData*iData,NSError*iConnectionError){
如果(!self.isCompleted){
if(iConnectionError){
[[MyImageFetchController sharedRunnerImageFetchControllerMy]urlFailed:self.imageURL];
}
UIImage*anImage=[UIImage-imageWithData:iData];
如果(动画){
[MyUtilities缓存文件:名为:[self.imageURL runnerMD5HashMy]的anImage到目录:[self.delegate cacheDirectoryForImages]];
}否则{
[[MyImageFetchController sharedRunnerImageFetchControllerMy]urlFailed:self.imageURL];
}
[self.delegate operation completedforurl:self.imageURL];
self.isCompleted=是;
}
}];
}
-(无效)requestTimedOut{
self.isCompleted=是;
[self.timeoutTimer invalidate];
self.timeoutTimer=nil;
[[MyImageFetchController sharedRunnerImageFetchControllerMy]urlFailed:self.imageURL];
[self.delegate operation completedforurl:self.imageURL];
}
@结束
你为什么不打电话

[self.delegate operationCompletedForURL:self.imageURL];
在这里面,如果

if (iConnectionError) {

另一方面,您不应该在该块中使用self,您应该使用一个_块变量。

您需要一个运行循环来使计时器工作,类似这样:

- (void)main
{
    // your code
    yourTimer = ... // create your timer

    NSRunLoop* runLoop = [NSRunLoop currentRunLoop];
    [runLoop addTimer:yourTimer forMode:NSRunLoopCommonModes];
    [runLoop run];
}

哦,还有,我想最好在main中设置自己的自动释放池。

不管怎样,这都会被调用,因为这句话不在任何if或else中。是的,你是对的。但是在没有计时器的情况下是否正确调用了委托?最好的选择是使用请求的超时时间(就像你看起来的那样),而不是使用计时器。是的,但是请求的超时时间并不保证在这段时间内实际超时请求。如果建立服务器连接需要时间,那么它可以工作,但一旦建立了服务器连接,并且服务器的响应稍微迟缓,那么它将遵循默认超时。请检查:Steven Fisher说,要使NSTimer触发其创建的线程的运行循环,需要继续存在,但在发送NSURLConnection请求后,操作线程立即死亡。尝试在主线程中启动计时器。为什么需要计时器?您已经在URL请求上设置了超时,因此最迟应在5秒后调用完成处理程序,如果请求超时,则应使用
iData==nil
。Martin,他确实有问题。从setTimeoutInterval上的NSMutableRequest.h注释中,“因此,当发生负载活动的实例时(例如,从网络接收到请求的字节),请求的空闲间隔重置为0”,因此如果他将间隔设置为5,但连接需要4个数据块,每个数据块需要2秒到达,连接甚至可能不会超时。