2016-03-30 13 views
1
のサブクラス

内側からNSURLSession方法I自分のアプリケーション、私が持っているカスタムセルとテーブルビュー、持っている:コールNSOperation

@property (weak, nonatomic) IBOutlet UIImageView *image; 
@property (weak, nonatomic) IBOutlet UILabel *nameOfImage; 
@property (weak, nonatomic) IBOutlet UIButton *start; 

を私はスタートボタンの多くを押して(非同期に任意の数の画像をダウンロードする必要があります)。この目的のために、私はNSOperation - MyOperationQueueのサブクラスを作成しました。それの実装は次のようになります。

- (NSURLSession *) configureSession //it visits it 
    { 
NSURLSession *session = [NSURLSession sessionWithConfiguration:config delegate:self.tableView **delegateQueue:self**]; //self - warning - incompatible pointer type sending "MyOperationQueue" to "NSOperationQueue" _Nullable. 

} 

-(void)URLSession:(NSURLSession *)session 
     downloadTask:(NSURLSessionDownloadTask *)downloadTask 
     didWriteData:(int64_t)bytesWritten 
    totalBytesWritten:(int64_t)totalBytesWritten 
    totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite // don't visit 

-(void)URLSession:(NSURLSession *)session 
    downloadTask:(NSURLSessionDownloadTask *)downloadTask 
didFinishDownloadingToURL:(NSURL *)location // don't visit 

私はテーブルビューでの方法でカスタムキューを作成します:私もNSURLSession方法は、ここで説明している。この方法の中

- (id)initWithURL:(NSURL*)url andRaw:(NSInteger)row 
{ 
    if (![super init]) 
     return nil; 
    [self setTargetURL:url]; 
    [self setCurrentCell:row]; 
    self.customCell = [[CustomTableViewCell alloc]init]; 
    self.tableView = [ContentTableView sharedManager]; 
    return self; 
} 

- (void)main 
{ 
    if ([self isCancelled])return; 
    self.defaultSession = [self configureSession]; 
    NSURLSessionDownloadTask *task = [self.defaultSession downloadTaskWithURL:self.targetURL]; 
    if ([self isCancelled]) return; 
    [task resume]; 
} 

- (void)cancel 
{ 
    self.isCancelled = YES; 
     if(self.downloadTask.state == NSURLSessionTaskStateRunning) 
     [self.downloadTask cancel]; 
} 

- (void)didClickStartAtIndex:(NSInteger)cellIndex withData:(CustomTableViewCell*)data 
    { 
     NSURL *url = [NSURL URLWithString: tmp.imeageURL]; 
     MyOperationQueue * one = [[MyOperationQueue alloc]initWithURL:url andRaw:self.selectedCell]; 
     [self.queue addOperation:one]; 
    } 

ザ・イメージがまったく読み込まれていない場合、キューは単に設定メソッドに入ります。何が間違っているかアドバイスしてください。 ありがとうございます。

EDIT: 更新UI:

-(void)URLSession:(NSURLSession *)session 
    downloadTask:(NSURLSessionDownloadTask *)downloadTask 
didFinishDownloadingToURL:(NSURL *)location 
{ 
    NSLog(@"didFinishDownloadingToURL - Queue"); 
    NSData *d = [NSData dataWithContentsOfURL:location]; 
    UIImage *im = [UIImage imageWithData:d]; 
    dispatch_async(dispatch_get_main_queue(), ^{ 
     self.customCell.image.image = im; 
     self.customCell.realProgressStatus.text = @"Downloaded"; 
     [self.tableView.tableView reloadData]; 
    }); 
} 
+0

ところで、あなたの 'cancel'メソッドでは、' [super cancel] 'を呼んで、標準の' NSOperation'の振る舞いを楽しんでいるでしょう。また、 'main'では' isFinished' KVOを必ず実行してください。最後に、 'NSOperation'クラスを非同期に定義したとします。 – Rob

+0

@Rob、私はちょうどそれのサブクラスを作成しました、私はそれが非同期でなければならないと言及したことはありません、どこでそれを行う必要がありますか? – Melany

+0

「NSURLSession」が非同期であるため、非同期である必要があります。だから(a) 'isAsynchronous'は' true'を返さなければなりません。 (b) 'isExecuting'と' isFinished'KVOを実行し、同様の名前のメソッドを使って正しい値を返す必要があります。 "非同期NSOperation'サブクラス"を検索すると、そのすべてのものについて多くのヒットが見つかる可能性があります。しかし、あなたは間違いなくこの非同期操作を行う必要があります。そうしないと、デリゲートメソッドが呼び出される前に操作が終了し、割り当てが解除されます。 – Rob

答えて

1

あなたのクラスはNSOperationのサブクラスでは、ないNSOperationQueueは、だから、NSURLSessionオブジェクトのターゲット・キューとしてselfを使用するように指定することはできません。実際には、デリゲートメソッドがどのキューで実行されているか気にしないので、操作キューパラメータにはnilを使用するだけです。また、必要に応じて独自の操作キューを作成することもできます。しかし、selfは使用できません。

しかし、すべてのUI更新をメインキューに戻してください。

また、非同期NSOperationサブクラスにする必要があります。そうしないと、デリゲートメソッドが呼び出される前に操作が終了し、割り当てが解除されます。

小さな見方では、このクラスの名前をMyOperationに変更して、操作と操作キューの混同を避けることをお勧めします。

+0

ありがとう、私はメインメソッドの内部NSOperationキューのインスタンスを作成し、自己の代わりにそれを追加する必要がありますか? – Melany

+0

すべてのチュートリアルで、OperationQueueではなくNSOperationのサブクラスを作成する必要があることが分かりました。 – Melany

+0

NSOperationをサブクラス化することは間違いありません。しかし、 'NSURLSession'の' queue'パラメータのために、 'NSURLSession'がどのキューを使用しているか気にしないので、' nil'だけを使用します。 (あなたの操作のためのキューと 'NSURLSession'が使用するキューを混同しないでください。)UIの更新をメインキューに戻すようにしてください。 – Rob