Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/cocoa/3.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 将NSO操作保留在队列中,即使它已完成_Ios_Cocoa_Nsoperation - Fatal编程技术网

Ios 将NSO操作保留在队列中,即使它已完成

Ios 将NSO操作保留在队列中,即使它已完成,ios,cocoa,nsoperation,Ios,Cocoa,Nsoperation,通常,一旦一个NSOperation的main方法完成,操作被标记为完成,并从队列中删除。但是,我的op会打网络电话,我想处理重试。如何将NSOperation保存在NSOperationQueue中,直到我明确表示可以删除它为止?我无法找到我在当前项目中所做工作的原始来源 我已将NSOperation子类化并执行此操作 在.m中添加私有属性 @property (nonatomic) BOOL executing; @property (nonatomic) BOOL finished; @p

通常,一旦一个
NSOperation
main
方法完成,操作被标记为完成,并从队列中删除。但是,我的op会打网络电话,我想处理重试。如何将
NSOperation
保存在
NSOperationQueue
中,直到我明确表示可以删除它为止?

我无法找到我在当前项目中所做工作的原始来源

我已将NSOperation子类化并执行此操作

在.m中添加私有属性

@property (nonatomic) BOOL executing;
@property (nonatomic) BOOL finished;
@property (nonatomic) BOOL completed;
初始化操作

- (id)init
{
    self = [super init];
    if (self) {
        _executing = NO;
        _finished = NO;
        _completed = NO;
    }
    return self;
}
- (void)completeOperation {
    [self willChangeValueForKey:@"isFinished"];
    [self willChangeValueForKey:@"isExecuting"];

    self.executing = NO;
    self.finished = YES;

    [self didChangeValueForKey:@"isExecuting"];
    [self didChangeValueForKey:@"isFinished"];
}
添加函数以返回属性

- (BOOL)isExecuting { return self.executing; }
- (BOOL)isFinished { return self.finished; }
- (BOOL)isCompleted { return self.completed; }
- (BOOL)isConcurrent { return YES; }
在“开始”函数中(这是operationQueue调用的位

- (void)start
{
    if ([self isCancelled]) {
        [self willChangeValueForKey:@"isFinished"];
        self.finished = YES;
        [self didChangeValueForKey:@"isFinished"];
        return;
    }

    // If the operation is not canceled, begin executing the task.
    [self willChangeValueForKey:@"isExecuting"];
    self.executing = YES;
    [self didChangeValueForKey:@"isExecuting"];

    [NSThread detachNewThreadSelector:@selector(main) toTarget:self withObject:nil];
}
然后把你的工作代码

- (void)main
{
    @try {
        //this is where your loop would go with your counter and stuff
        //when you want the operationQueue to be notified that the work
        //is done just call...
        [self completeOperation];
    }
    @catch (NSException *exception) {
        NSLog(@"Exception! %@", exception);
        [self completeOperation];
    }
}
为completeOperation编写代码

- (id)init
{
    self = [super init];
    if (self) {
        _executing = NO;
        _finished = NO;
        _completed = NO;
    }
    return self;
}
- (void)completeOperation {
    [self willChangeValueForKey:@"isFinished"];
    [self willChangeValueForKey:@"isExecuting"];

    self.executing = NO;
    self.finished = YES;

    [self didChangeValueForKey:@"isExecuting"];
    [self didChangeValueForKey:@"isFinished"];
}
就这样

只要你有这些,那么操作就会工作

您可以添加任意数量的其他函数和属性

事实上,我已经对这个类进行了子类化,因为我有一个函数,可以为不同类型的对象做所有的工作(这是一个上传的东西)

- (void)uploadData
{
    //subclass this method.
}
然后我在子类中只有一个自定义的“uploadData”方法


我发现这非常有用,因为它可以对何时完成操作等进行精细控制。

如果对NSOperation进行子类化,则可以明确地告诉它何时完成。请在NSOperation子类中记录尝试次数,并仅在成功或达到预定尝试次数时才告诉它已完成。是否可以您只需将另一个NSOperation重新提交到队列以重试?@Fogmeister等待,因此如果我将NSOperation子类化,它在我说它已完成之前不会“完成”?它与
main
方法无关?NSOperation子类只是一个状态机。如果您不将其设置为complete(我记不起确切的属性)然后它就不会完成。我会在操作中设置一个循环,只需继续尝试指定的次数。如果成功,则设置为完成。如果失败,则允许循环继续。如果达到尝试次数,则放弃循环并设置为完成。@Fogmeister code completion在我输入setX..我必须手动合成该属性还是什么?感谢代码示例。这非常有用。两个问题:是否有必要调用willChange/didChange值方法?调用self.executing句柄不是自动的吗?为什么在主方法中使用异常处理程序?这是你的习惯吗或者这是一种推荐的做法,如果是,原因是什么?是的,这是必要的。队列具有属性“isExecuting”的观察者,该属性与我的“executing”不同。这样做会强制队列运行-(BOOL)iExecuting。这是我第一次使用它。我在其他地方读到过关于它的文章,它极大地改进了我的代码库。但从现在起,它将是我的任务。我的精简工具包可能是对另一个SO问题或其他问题的响应,找不到它。异常处理程序是我自己的,因为我的操作都是通过网络进行的k、 当我没有连接时,它阻止了整个失败(或应用程序崩溃)。你可能不需要它们。我找到了!这是我自己问题的答案。