2016-06-30 5 views
0

Ich möchte überprüfen, ob ein Objekt definiert ist oder existiert mit Swift.Wie überprüfe ich Swift, wenn ein Objekt ungültig ist?

Etwas wie folgt aus:

if (isset(Object)){ 

} 

Ich habe ein Problem mit:

if let x = myObject.property { 
    //My code 
} <- Here I got 'EXC_BAD_ACCESS' 

Normalerweise ist der Code funktioniert, aber manchmal fehlschlagen. Wenn in dem Debug-myObject scheitern wird definiert und haben andere Eigenschaften, aber wenn ich versuche:

myObject.property in Debugger zeigt: "Invalid Ausdruck"

myObject.otherProperty < - Works!

Es ist nicht das erste Mal, dass ich diese Nachricht habe, die letzte war mit einem Objekt eines UIViewController und der Eigenschaft 'view'. Diese Zeit tritt mit einem Objekt einer benutzerdefinierten Klasse auf.

Vielen Dank im Voraus!

Mein Code:

class DetallesEntidadController: UIViewController { 
    override func viewDidLoad() { 
     super.viewDidLoad() 

     if let canal = Canal.getCanal(getManagedContext()) { 
      if let imagenFondo: Imagen = canal.imagenFondo { 
       if let view = self.view { 
        let ivBackgroundImage = UIImageView(image: Utils.loadImageFromPath(imagenFondo.nombreFichero!)) 
        ivBackgroundImage.frame = view.frame 
        var bottomView = CGFloat() 
        if let height = self.navigationController?.navigationBar.frame.height { 
         ivBackgroundImage.frame.origin.y = -height-Utils.getStatusBarHeight() 
         bottomView = view.frame.origin.y+view.frame.size.height-Utils.getStatusBarHeight()-height 
        } else { 
         bottomView = view.frame.origin.y+view.frame.size.height-Utils.getStatusBarHeight() 
        } 
        ivBackgroundImage.frame.origin.y = bottomView - ivBackgroundImage.frame.height 

        view.addSubview(ivBackgroundImage) 
        view.sendSubviewToBack(ivBackgroundImage) 
       } 
      } <- Thread 1: EXC_BAD_ACCESS (code=1, address=0x........) 
     } 
    } 
} 

Meine Klassen:

import Foundation 
import CoreData 

class Canal: NSManagedObject { 
    @NSManaged var titulo: String? 
    @NSManaged var version: NSNumber? 
    @NSManaged var imagenFondo: Imagen? 
} 

internal func persist(managedContext: NSManagedContext, xmlIndexerCanal: XMLIndexer){...} 
internal static func getCanal(managedContext: NSManagedContext) -> Canal? {...} 

import Foundation 
import CoreData 

class Imagen: NSManagedObject { 

    @NSManaged var nombreFichero: String? 
    @NSManaged var titulo: String? 
    @NSManaged var url: String? 

    internal func persist(managedContext: NSManagedObjectContext, strUrl: String){...} 

} 

Die Eigenschaft, die es 'canal.imagenFondo' scheitern aber 'canal.titulo' arbeitet, wird der Fehler passiert nur manchmal.

Hinzugefügt:

func getManagedContext() -> NSManagedObjectContext { 
    let delegado = UIApplication.sharedApplication().delegate as! AppDelegate 
    return delegado.managedObjectContext 
} 

lazy var managedObjectContext: NSManagedObjectContext = { 
    // Returns the managed object context for the application (which is already bound to the persistent store coordinator for the application.) This property is optional since there are legitimate error conditions that could cause the creation of the context to fail. 
    let coordinator = self.persistentStoreCoordinator 
    var managedObjectContext = NSManagedObjectContext(concurrencyType: .PrivateQueueConcurrencyType) 
    managedObjectContext.persistentStoreCoordinator = coordinator 
    return managedObjectContext 
}() 

Lösung (Danke Rob Napier):

Meine NSManagedObject verlangen, dass der Kontext, in dem selben Thread verwendet werden, die es erstellt.

func getManagedContextMainQueue() -> NSManagedObjectContext { 
    let delegado = UIApplication.sharedApplication().delegate as! AppDelegate 

    let coordinator = delegado.persistentStoreCoordinator 
    let managedObjectContext = NSManagedObjectContext(concurrencyType: .MainQueueConcurrencyType) 
    managedObjectContext.persistentStoreCoordinator = coordinator 
    return managedObjectContext 
} 
+2

Bitte geben Sie Ihre tatsächlichen Code- und Eigenschaftsdefinitionen an. Es ist unmöglich zu sehen, was ohne das passiert. –

+0

Hinzugefügt :) Danke. – Gonzalo1987

+1

Vielleicht ist das Problem ähnlich zu [dies] (http: // stackoverflow.com/questions/28092971/swift-gibs-error-thread-1-exc-bad-accesscode-1-adresse-0x0-wenn-zugreifend-n)? – Leonardo

Antwort

1

Dieser Code ist unsicher, und ist wahrscheinlich die Ursache des Problems: Die Methode getManagedContext() wurde ersetzt

if let canal = Canal.getCanal(getManagedContext()) { 
     if let imagenFondo: Imagen = canal.imagenFondo { 

canal ist ein verwaltetes Objekt. Es kann nur auf die Warteschlange zugegriffen werden, die seinem Kontext zugeordnet ist. Verwaltete Objekte sind nicht Thread-sicher. Ich vermute, dass getManagedContext() einen Kontext zurückgibt, der nicht an die Hauptwarteschlange (UI) gebunden ist. In diesem Fall ist canal.imagenFondo illegal.

Da dies ein UI-Code ist, besteht die korrekte Vorgehensweise darin, einen verwalteten Objektkontext zu erstellen, der an die Hauptwarteschlange (NSManagedObjectContext(concurrencyType: .MainQueueConcurrencyType)) gebunden ist und alle Objekte mit UI-Zugriff über diesen Kontext abruft.

Für Nicht-UI-Code müssen Sie häufig den Zugriff auf verwaltete Objekte in einem context.performBlock() umschließen, um sicherzustellen, dass der gesamte Zugriff in der richtigen Warteschlange erfolgt.

Siehe die Core Data Concurrency Anleitung für mehr.

+0

func getManagedContext() -> NSManagedObjectContext { lassen Sie delegado = UIApplication.sharedApplication(). Delegate als! AppDelegate return delegado.managedObjectContext } Es ist schlecht? Normalerweise funktioniert – Gonzalo1987

+1

Wie wurde 'delegado.managedObjectContext' erstellt? –

+0

Ich kann das NSManagedObject im Thread verwenden (die Eigenschaft canal.titulo funktioniert gut) – Gonzalo1987

Verwandte Themen