ios - 如果对象无效,如何检查 Swift?

标签 ios xcode swift properties defined

我想使用 Swift 检查对象是否已定义或存在。

像这样:

if (isset(Object)){

}

我在使用时遇到问题:

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

通常代码可以工作,但有时会失败。当调试失败时 myObject 被定义并具有其他属性,但是当我尝试时:

调试器中的 myObject.property 显示:“无效表达式”

myObject.otherProperty <- 有效!

这不是我第一次收到该消息,上一次是关于 UIViewController 的对象和属性“view”。这次发生在自定义类的对象上。

提前致谢!

我的代码:

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

我的类(class):

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
}

最佳答案

此代码不安全,很可能是导致问题的原因:

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

canal 是一个托管对象。它只能在与其上下文关联的队列上访问。托管对象不是线程安全的。我怀疑 getManagedContext() 会返回一个未绑定(bind)到主 (UI) 队列的上下文。在这种情况下,canal.imagenFondo 是非法的。

由于这是 UI 代码,正确的方法是创建一个绑定(bind)到主队列的托管对象上下文 (NSManagedObjectContext(concurrencyType: .MainQueueConcurrencyType)) 并通过以下方式获取所有 UI 访问的对象那个上下文。

对于非 UI 代码,您通常需要将对托管对象的访问包装在 context.performBlock() 中,以确保所有访问都发生在正确的队列中。

参见 Core Data Concurrency更多指南。

关于ios - 如果对象无效,如何检查 Swift?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38127169/

相关文章:

ios - OAuth2 "social login"流程(允许通过 Facebook/Twitter 进行 OAuth2 身份验证): are there any examples/literature?

ios - 尝试将代码加载到我的 ios 设备时出现调试问题

ios - Swift 自定义 UITableViewCell 标签始终为零

ios - Moya/Alamofire - 具有相同键的 URL 编码参数

ios - swift 4 : cellForRowAt skipping last row

ios - xcconfig 文件中的 info.plist 键名

c# - Xamarin.Forms Shell GoToAsync 在 iOS 中无法按预期工作

ios - 将 Quartz 方法从 iOS 转换为 OSX

iphone - iOS - 如何在选择单元格时禁用 UITableView 滚动到顶部?

ios - 从 UILabel 文本掩码获取 PDF