performSelectorInBackground und EXC BAD ACCESS

  • performSelectorInBackground und EXC BAD ACCESS

    Hi,

    ich bräuchte mal wieder Hilfe. Kurzer Anriss. Ich habe in meinem Root View eine TabBar und einen WebView.
    Sobald ich einen Tab auswähle, beginnt der WebView etwas zu laden. Dieses Laden dauert ein bisschen.
    Deswegen habe ich jetzt diesen Laden-Prozess mittels performSelectorInBackround: in den "Hintergrund" geschoben.
    Leider bekomme ich jetzt, wenn ich etwas auswähle, und der Ladevorgang vorher noch nicht beendet ist einen Fehler.

    "EXC BAD ACCESS".. Ich nehme an dass es ein MultiThreading Problem ist (ohne den performSelectorInBackground kommt der
    Fehler nicht) und ich dafür noch einiges andere ändern muss.
    Leider kenne ich mich damit noch nicht aus und wollte daher mal fragen, ob es eine andere Möglichkeit gibt,
    wie ich dafür sorgen kann, dass wenn der Nutzer eine Tab auswählt, diese auch sofort im UI angezeigt wird.

    Anregungen zum performSelectorInBackground nehme ich natürlich auch sehr gerne entgegen.

    Danke! Maccie
  • Ja, den habe ich extra für die Methoden erzeugt, in denen mir Leaks in der Konsole angezeigt wurden.

    Was mich wundert ist, dass der Ladevorgang mit einer anderen Klasse durchgeführt wird. Und die erste Zeile von dieser Klasse,
    die aufgerufen wird ist einfach nur ein NSLog-Aufruf, in dem auf eine Instanzvariable der Klasse (Typ String) zugegriffen wird. Dieser führt zum EXC BAD ACCESS.

    Grüße

    Maccie
  • Du sagst, dass du das Laden im Hintergrund, also im Kontext eines Threads machst. Von einem Thread aus darfst du nicht auf ein (Web)View zugreifen. Es geht aus deinem Text nicht hervor, ob du das Laden selbst übernimmst (NSURLConnection) oder du in deinem Thread einfach nur das WebView zum Laden aufforderst, was in die Hose gehen würde und was auch ein Grund für den Fehler sein kann.
    Die Objective-Cloud ist fertig wenn sie fertig ist. Beta heißt Beta.

    Objective-C und Cocoa Band 2: Fortgeschrittene
    Cocoa/Objective-C Seminare von [co coa:ding].
  • Hi!

    Ich erzeuge in dem Background Thread einen HTML-String, den ich mittels:

    Quellcode

    1. [viewController.webview loadHTMLString:pageHtml baseURL:[NSURL URLWithString:self.formUrl]];

    dem WebView zum Anzeigen übergebe.

    Darf man sowas nicht?

    Grüße
  • Den String im Thread erzeugen darfst du. Im Thread darfst du

    Quellcode

    1. [viewController.webview loadHTMLString:pageHtml baseURL:[NSURL URLWithString:self.formUrl]];


    allerdings nicht aufrufen. Das solltest du mit performSelectorOnMainThread machen.
    Die Objective-Cloud ist fertig wenn sie fertig ist. Beta heißt Beta.

    Objective-C und Cocoa Band 2: Fortgeschrittene
    Cocoa/Objective-C Seminare von [co coa:ding].
  • Genau das habe ich gerade versucht. Ich habe den Aufruf jetzt wie folgt geändert:

    Im Background Thread:

    Quellcode

    1. NSDictionary *loadObjects = [[[NSDictionary alloc] initWithObjectsAndKeys:
    2. pageHtml, @"HTMLString",
    3. [NSURL URLWithString:self.formUrl], @"URLString", nil] autorelease];
    4. [[APPDELEGATE.navController.viewControllers objectAtIndex:0] performSelectorOnMainThread:@selector(loadPage:) withObject:loadObjects waitUntilDone:NO];


    Methode des View Controllers mit dem WebView:

    Quellcode

    1. - (void)loadPage:(NSDictionary *)objects {
    2. [webview loadHTMLString:[objects objectForKey:@"HTMLString"] baseURL:[objects objectForKey:@"URLString"]];
    3. }


    Leider kommt der Fehler immer noch..

    Maccie
  • Hi, ich wollte gerade ein Minimalprojekt erzeugen. Allerdings wird das extrem komplex das nachzubauen.

    Ich habe jetzt allerdings folgendes gesehen, ka wie ich das beim ersten mal übersehen konnte:
    Meine Methode die den Background Thread erzeugt sieht wie folgt aus:

    Quellcode

    1. [object performSelectorInBackground:@selector(loadWithIndex:) withObject:index];


    Index ist ein Integer. Der Compiler gibt mir hier eine Warnmeldung aus: ... argument 2 makes pointer from integer without a cast.
    Solange index den Wert 0 hat, geht alles. Solange index den Wert 1 annimmt, gehts schief: EXC BAD ACCESS:

    Hilft euch das weiter? Wie bekomme ich denn Warnmeldung weg? Kann mit der nichts anfangen, was heißt denn cast?

    Grüße,
    Maccie

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von Maccie ()

  • Maccie schrieb:

    Quellcode

    1. [object performSelectorInBackground:@selector(loadWithIndex:) withObject:index];


    Index ist ein Integer. Der Compiler gibt mir hier eine Warnmeldung aus: ... argument 2 makes pointer from integer without a cast.
    Solange index den Wert 0 hat, geht alles. Solange index den Wert 1 annimmt, gehts schief: EXC BAD ACCESS:

    Hilft euch das weiter? Wie bekomme ich denn Warnmeldung weg? Kann mit der nichts anfangen, was heißt denn cast?

    Nun, die Methode performSelectorInBackground:withObject: erwartet einen Zeiger auf ein Objekt als zweiten Parameter und Du übergibst einen Integer. Daher warnt Dich der Compiler, dass Du hier höchstwahrscheinlich etwas falsch machst. Verpacke also den Integer in ein Objekt. Da der Integer hier wohl ein Index sein soll, bietet sich die Klasse NSIndexSet dafür an.

    Ein Cast wäre eine Mitteilung an den Compiler, dass eine andere Interpretation eines Datentyps wirklich gewollt ist. Also zum Beispiel wenn ein Integer als Pointer interpretiert werden sollte, schreibt man (void *)integerVariable. Dafür sollte man aber einen wirklich triftigen Grund haben, so etwas tun zu wollen. Mir fällt da spontan aber keiner ein.

    Michael