2016-06-30 10 views
0

Я хотел бы проверить, определен ли объект или существует с помощью Swift.Как проверить Swift, если объект недействителен?

Что-то вроде этого:

if (isset(Object)){ 

} 

У меня есть проблемы с помощью:

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

Обычно код работает, но иногда терпят неудачу. При неудачной в отладке MyObject определяется и другие свойства, но когда я пытаюсь:

myObject.property отладчик показывает: «Invalid выражение»

< myObject.otherProperty - работает!

Это не первый раз, когда у меня есть это сообщение, последний был с объектом UIViewController и представлением свойства. Это время происходит с объектом пользовательского класса.

Заранее благодарен!

Мой код:

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........) 
     } 
    } 
} 

Мои классы:

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){...} 

} 

Свойство, которое не в состоянии это 'canal.imagenFondo' но 'canal.titulo' работает, ошибка только иногда случилось.

Добавлено:

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

Решение (Спасибо Rob Napier):

Мои NSManagedObject требуют, чтобы использоваться в том же потоке, что контекст, который его создал. Метод getManagedContext() был заменен на:

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

Пожалуйста, разместите свои фактические определения кода и свойств. Без этого невозможно понять, что происходит. –

+0

Добавлено :) Спасибо. – Gonzalo1987

+1

Возможно, проблема у вас похожа на [this] (http: // stackoverflow.ком/вопросы/28092971/быстроногий дает ошибки-нить-1-отл-плохо-accesscode-1-адресно-0x0-когда-доступ к-п)? – Leonardo

ответ

1

Этот код является небезопасным, и, скорее всего, причиной вашей проблемы:

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

canal является управляемым объектом. Доступ к нему можно получить только в очереди, связанной с ее контекстом. Управляемые объекты не являются потокобезопасными. Я подозреваю, что getManagedContext() возвращает контекст, который не привязан к основной (UI) очереди. В этом случае canal.imagenFondo является незаконным.

Поскольку это код пользовательского интерфейса, правильным подходом является создание контекста управляемого объекта, привязанного к основной очереди (NSManagedObjectContext(concurrencyType: .MainQueueConcurrencyType)) и выборки всех объектов с доступом через интерфейс через этот контекст.

Для кода, отличного от UI, вам часто необходимо обернуть доступ к управляемым объектам в context.performBlock(), чтобы убедиться, что весь доступ происходит в правой очереди.

См. Руководство для Core Data Concurrency.

+0

func getManagedContext() -> NSManagedObjectContext { let delegado = UIApplication.sharedApplication(). delegate as! AppDelegate вернуть delegado.managedObjectContext }. это плохо? Обычно работает – Gonzalo1987

+1

Как был 'delegado.managedObjectContext' создан? –

+0

Я могу использовать NSManagedObject в потоке (свойство canal.titulo работает отлично) – Gonzalo1987

 Смежные вопросы

  • Нет связанных вопросов^_^