如果对象无效,如何签入 Swift?
How to check in Swift if an object it's invalid?
我想使用 Swift.
检查对象是否已定义或存在
像这样:
if (isset(Object)){
}
我在使用时遇到问题:
if let x = myObject.property {
//My code
} <- Here I got 'EXC_BAD_ACCESS'
代码通常有效,但有时会失败。当调试失败时 myObject 被定义并具有其他属性,但是当我尝试时:
myObject.property 在调试器中显示:"Invalid expression"
myObject.otherProperty <- 有效!
这不是我第一次收到该消息,最后一次是关于 UIViewController 的对象和 属性 'view'。这次发生在自定义对象 class.
提前致谢!
我的代码:
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()
returns 一个未绑定到主 (UI) 队列的上下文。在那种情况下 canal.imagenFondo
是非法的。
因为这是 UI 代码,正确的方法是创建一个绑定到主队列 (NSManagedObjectContext(concurrencyType: .MainQueueConcurrencyType)
) 的托管对象上下文并获取所有 UI 访问的对象通过那个上下文。
对于非 UI 代码,您通常需要将对托管对象的访问包装在 context.performBlock()
中,以确保所有访问都发生在正确的队列中。
有关详细信息,请参阅 Core Data Concurrency 指南。
我想使用 Swift.
检查对象是否已定义或存在像这样:
if (isset(Object)){
}
我在使用时遇到问题:
if let x = myObject.property {
//My code
} <- Here I got 'EXC_BAD_ACCESS'
代码通常有效,但有时会失败。当调试失败时 myObject 被定义并具有其他属性,但是当我尝试时:
myObject.property 在调试器中显示:"Invalid expression"
myObject.otherProperty <- 有效!
这不是我第一次收到该消息,最后一次是关于 UIViewController 的对象和 属性 'view'。这次发生在自定义对象 class.
提前致谢!
我的代码:
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()
returns 一个未绑定到主 (UI) 队列的上下文。在那种情况下 canal.imagenFondo
是非法的。
因为这是 UI 代码,正确的方法是创建一个绑定到主队列 (NSManagedObjectContext(concurrencyType: .MainQueueConcurrencyType)
) 的托管对象上下文并获取所有 UI 访问的对象通过那个上下文。
对于非 UI 代码,您通常需要将对托管对象的访问包装在 context.performBlock()
中,以确保所有访问都发生在正确的队列中。
有关详细信息,请参阅 Core Data Concurrency 指南。