2017-04-20 4 views
0

Ich versuche Protokoll/Delegierten mit perform zu implementieren, aber ich bin immer diese Fehlermeldung:Swift: Wert des Typs hat kein Mitglied ‚peformSelector‘

Value of type 'DoingSomething' has no member 'peformSelector' 

Hier meine Implementierung ist:

import UIKit 
protocol DoingSomethingDelegate { 
    // delegate function 
} 

class DoingSomething { 
    func goDoSomething() 
     self.performSelector(onMainThread: #selector(self.processSomething()), with: nil, waitUntilDone: true) 
    } 
    func processSomething() { 

     print("I'm done") 
    } 
} 

Aber wenn ich die Funktionen auf den ViewController verschiebe, habe ich keine Fehler. Jeder von Ihnen weiß warum der Fehler oder wie kann ich diesen Fehler beheben?

Ich werde Ihre Hilfe wirklich zu schätzen wissen.

+0

Es ist eine 'NSObject' Methode und Ihre Klasse erbt nicht von' NSObject' – dan

+1

Betrachten Sie 'DispatchQueue.main.sync'. 'performSelector ...' ist veraltet (in Swift). – vadian

+0

@dan, Hinzufügen von NSObject zur Klasse machte den Trick: Klasse DoingSomething: NSObject – user2924482

Antwort

1

Per @ Dan Kommentar habe ich die Änderungen:

class DoingSomething:NSObject { 

    func goDoSomething() { 

     self.performSelector(onMainThread: #selector(self.processSomething), with: nil, waitUntilDone: true) 
    } 

    func processSomething() { 

     print("I'm done") 
    } 
} 

Jetzt funktioniert!

+0

Dies ist keine gute Lösung. Warum fügen Sie das unnötige Gepäck hinzu, indem Sie 'NSObject' erweitern, nur damit Sie' performSelector' aufrufen können, wenn die viel bessere Lösung zu tun ist, wie @vadian angegeben hat, und verwenden Sie 'DispatchQueue.main.async'. – rmaddy

+0

@rmaddy, warum DispatchQueue.main.sync ist die bessere Option als performSelector? – user2924482

+0

Weil Sie Swift verwenden. Warum "NSObject" erweitern? Und mit 'DispatchQueue' haben Sie so viele Optionen. 'performSelector' ist sehr eingeschränkt und es ist zu einfach, die '# selector'-Syntax falsch zu bekommen. – rmaddy

1

Wie @vandian in seinem Kommentar vorschlägt, sollten Sie stattdessen über GCD nachdenken. Der entsprechende Code wäre:

Es gibt eine Reihe von Vorteilen bei der Verwendung von async(). Sie können den Code in einer Zeile bereitstellen, ohne eine separate Funktion schreiben zu müssen, die das Lesen und Verwalten erleichtert. Die Schließung Sie ausführen hat Zugriff auf den umgebenden Gültigkeitsbereich, so dass Sie innerhalb dieser Code Variablen aus Ihrer Funktion verwenden, zB:

func localScopeFunc { 
    var x: Int = 6 
    DispatchQueue.main.async { 
    //This block of code has access to the local variables from localScopeFunc 
    print("x = \(x)") 
    } 
} 

Mit perform() und es Varianten Sie funktioniert nur mit Null aufrufen kann, eine oder 2 Argumente, und diese Argumente müssen NSObjects sein.

Die Erzwingung, dass ein Objekt eine Unterklasse von NSObject ist, hat auch einige kleinere Nachteile. Dies zwingt den Compiler zum dynamischen Dispatching, was etwas langsamer ist als das statische Dispatching, das Swift verwendet.

+0

performSelector hat die Option zu warten, bis es fertig ist. Wird DispatchQueue.main.async gewartet, bis der Code verarbeitet wurde? – user2924482

+0

@ user2924482 Wenn Sie warten möchten und 100% wissen, dass Sie sich noch nicht in der Hauptwarteschlange befinden, verwenden Sie 'DispatchQueue.main.sync' anstelle von' DispatchQueue.main.async'. – rmaddy

+0

@rmaddy, das macht Sinn. Vielen Dank – user2924482

Verwandte Themen