【问题标题】:object of NSOperation doesn't removed from NSOperationQueue after executingNSOperation 的对象在执行后不会从 NSOperationQueue 中删除
【发布时间】:2016-04-02 23:55:55
【问题描述】:

在我的 NSOperation 子类中,我设置了 4 个标志,当一个操作完成执行时,它不会被删除到 NSOperation 队列中,它是在开始时添加的,这会导致我的应用程序出现很多问题。 我想我设置这些标志的方式不正确,请你帮忙。因为我确实花了很多时间来确定这个问题。

@property(assign, nonatomic) BOOL isCancelled;
@property(nonatomic, getter=isExecuting) BOOL executing;
@property(nonatomic, getter=isFinished) BOOL finished;
@property(readonly, getter=isAsynchronous) BOOL asynchronous;

//in initialisation 
- (id)initWithURL:(NSURL*)url andRaw:(NSInteger)row
{
    if (![super init])
        return nil;
    [self setTargetURL:url];

    return self;
}
//the way I override KVO
- (BOOL)isExecuting
{
     NSLog(@"Exec");
    return (self.defaultSession != nil);//it doesn't work
}

- (BOOL)isFinished
{
    NSLog(@"Finished");
    return (self.defaultSession == nil); //it doesn't work, so I explicitly set the value
}

- (BOOL)isAsynchronous
{
    return YES;
}

- (void)cancel
{
    [super cancel];
    [self willChangeValueForKey:@"isExecuting"];
    [self willChangeValueForKey:@"isFinished"];
    self.isExecuting = NO;
    self.isFinished  = YES;
    [self didChangeValueForKey:@"isFinished"];
    [self didChangeValueForKey:@"isExecuting"];

    if(self.downloadTask.state == NSURLSessionTaskStateRunning)
        [self.downloadTask cancel];
    [self finish];
 } 
- (void)finish
{
    [self willChangeValueForKey:@"isExecuting"];
    [self willChangeValueForKey:@"isFinished"];
    self.defaultSession = nil; //NSURLSession
    self.isFinished  = YES;
    [self didChangeValueForKey:@"isFinished"];
    [self didChangeValueForKey:@"isExecuting"];
 }

提前谢谢你

编辑: 最后我发现了问题——它是队列中的 NSURLSession 。它保持对队列的强引用,不允许从 NSOperationQueue 中释放和删除它。

【问题讨论】:

    标签: ios key-value-observing nsoperationqueue


    【解决方案1】:

    我也做过同样的事情,虽然在 Swift 中。

    我有几个方面的实现方式不同,如下所列:

    • 我注意到我们不必在 异步操作。 NSOperation 的取消默认行为 方法是将 self.cancelled 布尔值设置为 true。
    • self.executing 应仅在覆盖的 start() 操作方法内设置为 true,而不是在 init 中(不确定这是否会导致任何问题)。同样在 start() 方法中设置 self.executing = true 之前,我确保布尔值 self.cancelled 为 false。如果 self.cancelled = true,我们应该设置 self.finished = true。
    • 另外,我为 isExecuting 和 isFinished 属性创建了一个“didSet”属性观察器,我在其中调用了 willChangeValueForKey 和 didChangeValueForKey。我不是 100% 确定如何在 Obj C 中复制 didSet 行为。(This 说要覆盖 setter)

    请参阅 Ray Wenderlich 的“并发”视频教程,其中 Sam DAvies 解释了为异步操作创建 NSoperation 子类。请注意,它仅适用于订阅者,并在 Swift 中进行了解释。我相信如果你修复了第 1 点和第 2 点,你应该会看到你的问题得到了解决。

    【讨论】:

    • 谢谢你,我会尽量按照你的指示去做,很遗憾我不是Ray Wenderlich的订阅者(.
    • 如果可以的话,我强烈建议您成为其中的一员。他们有一些很棒的教程。 raywenderlich.com/video-tutorials
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-11-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-04-28
    • 1970-01-01
    相关资源
    最近更新 更多