1

ich meine Bewerbung Ich habe Tabellenansicht mit benutzerdefinierten Zelle, die hat:Anruf NSURLSession Methode aus dem Inneren der Unterklasse von NSOperation

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

ich asynchron beliebig viele Bilder herunterladen müssen (durch eine Menge Starttasten drücken). Zu diesem Zweck habe ich eine Unterklasse von NSOperation - MyOperationQueue erstellt. Umsetzung sieht es wie folgt aus:

- (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]; 
} 

unter dieser Methoden, die ich auch hier NSURLSession Methoden beschrieben:

- (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 

Ich schaffe in Verfahren in Tableview die benutzerdefinierte Warteschlange:

- (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]; 
    } 

Die Bild ist überhaupt nicht geladen, die Warteschlange nur in Konfigurationsmethode eingeben und das ist alles. Bitte rate mir, was falsch ist? Vielen Dank im Voraus.

EDIT: Aktualisierung 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

BTW, in Ihrer 'cancel' Methode möchten Sie wahrscheinlich' [super cancel] 'aufrufen, damit Sie das Standardverhalten' NSOperation' genießen können. Stellen Sie in 'main' sicher, dass Sie die' isFinished' KVO ausführen. Schließlich nehme ich an, dass Sie Ihre 'NSOperation'-Klasse als asynchron definiert haben? – Rob

+0

@Rob, ich habe gerade die Unterklasse davon erstellt, ich habe nie erwähnt, dass es asynchron sein sollte, wo soll ich das tun? – Melany

+0

Ja, es muss asynchron sein, da 'NSURLSession' asynchron ist. Also (a) "isAsynchronous" muss "true" zurückgeben; (b) Sie müssen "isExecuting" und "isFinished" KVO ausführen und haben ähnliche Methoden, die die korrekten Werte zurückgeben. Wenn Sie nach "asynchrone' NSOperation'-Unterklasse "suchen, werden Sie wahrscheinlich viele Treffer für all diese Dinge finden. Sie müssen diese asynchrone Operation jedoch unbedingt vornehmen, da andernfalls die Operation beendet und aufgehoben wird, bevor eine der Delegatmethoden aufgerufen wird. – Rob

Antwort

1

Ihre Klasse ist eine Unterklasse von NSOperation, nicht NSOperationQueue So können Sie festlegen, es nicht self als Zielwarteschlange zu verwenden, für das NSURLSession Objekt. Ehrlich gesagt, würden Sie einfach nil für den Operationswarteschlangenparameter verwenden, da es Ihnen egal ist, auf welcher Warteschlange die Delegatmethoden ausgeführt werden. Oder Sie können Ihre eigene Operationswarteschlange erstellen, wenn Sie möchten. Aber Sie können self nicht verwenden.

Stellen Sie jedoch sicher, dass alle UI-Aktualisierungen zurück in die Hauptwarteschlange gesendet werden.

Sie müssen dies auch zu einer asynchronen Unterklasse NSOperation machen, sonst wird die Operation beendet und die Zuordnung aufgehoben, bevor Ihre Delegiertenmethoden überhaupt eine Chance erhalten, aufgerufen zu werden.

Als kleine Beobachtung würde ich vorschlagen, diese Klasse in MyOperation umzubenennen, um eine Verwechslung zwischen Operationen und Operationswarteschlangen zu vermeiden.

+0

danke, also sollte ich innerhalb der Hauptmethode eine Instanz von NSOperation Queue erstellen und es anstelle von selbst hinzufügen? – Melany

+0

In allen Tutorials sah ich, dass es notwendig ist, eine Unterklasse von NSOperation zu erstellen, nicht OperationQueue – Melany

+0

Subclassing 'NSOperation' ist korrekt. Aber für den 'queue' Parameter von' NSURLSession' würde ich einfach 'nil' verwenden, da es dir wahrscheinlich egal ist, welche Warteschlange' NSURLSession' benutzt. (Verwechseln Sie die Warteschlange für Ihre Operationen nicht mit der Warteschlange, die 'NSURLSession' verwendet.) Stellen Sie sicher, dass die UI-Updates zurück in die Hauptwarteschlange gesendet werden. – Rob

Verwandte Themen