2015-02-10 95 views
1

我有以下的代码片段,我有一些设备崩溃:Swift:Downcast导致应用程序崩溃,为什么?

Crashed: com.apple.root.default-qos 
EXC_BAD_ACCESS KERN_INVALID_ADDRESS at 0x00000000cbd 

代码:

var obj:AnyObject = command.arguments[0] as AnyObject! 
var theData:AnyObject = obj["getContactImagesByEmails"] as AnyObject! 

if let contactImagesByEmails:AnyObject = obj["emails"]{ 
    if contactImagesByEmails is Array<String>{ 
/*line 176*/ let array:Array<String> = 
        contactImagesByEmails as Array<String> // CRASH happens here 

     results = WmSqliteImagesModel.getInstance.getImagesByEmailAsWmContactImage(array) as Dictionary<String,AnyObject> 
      } 
     } 

完整的堆栈跟踪

Thread : Crashed: com.apple.root.default-qos 
0 libswiftCore.dylib    0x0000000100559794 swift_unknownRetain + 32 
1 MyApp      0x000000010017c8a0 MyApp.Plugin.(getContactImagesByEmails (MyApp.Plugin) -> (ObjectiveC.CDVInvokedUrlCommand) ->()).(closure #1) (Plugin.swift:176) 
2 MyApp      0x000000010017c8a0 MyApp.Plugin.(getContactImagesByEmails (MyApp.Plugin) -> (ObjectiveC.CDVInvokedUrlCommand) ->()).(closure #1) (Plugin.swift:176) 
3 MyApp      0x00000001001790b0 partial apply forwarder for reabstraction thunk helper from @callee_owned() -> (@unowned()) to @callee_owned (@in()) -> (@out()) with unmangled suffix "125" (Plugin.swift:62) 
4 MyApp      0x0000000100179120 partial apply forwarder for reabstraction thunk helper from @callee_owned (@in()) -> (@out()) to @callee_owned() -> (@unowned()) with unmangled suffix "128" (Plugin.swift:62) 
5 libdispatch.dylib    0x00000001937e13ac _dispatch_call_block_and_release + 24 
6 libdispatch.dylib    0x00000001937e136c _dispatch_client_callout + 16 
7 libdispatch.dylib    0x00000001937ed40c _dispatch_root_queue_drain + 1152 
8 libdispatch.dylib    0x00000001937ee75c _dispatch_worker_thread3 + 108 
9 libsystem_pthread.dylib  0x00000001939bd2e4 _pthread_wqthread + 816 

Plugin.swift:176点到:

let array:Array<String> = contactImagesByEmails as Array<String> 

我想念什么吗?我认为这个代码应该是安全的。

如果contactImagesByEmails is Array<String>返回true,为什么contactImagesByEmails as Array<String>失败?

请帮帮忙,

[编辑]

command有型的CDVInvokedUrlCommand

@interface CDVInvokedUrlCommand : NSObject { 
    NSString* _callbackId; 
    NSString* _className; 
    NSString* _methodName; 
    NSArray* _arguments; 
} 
+0

你期望'var obj:AnyObject = command.arguments [0]作为AnyObject!'做什么?我可以看到它是如何编译的,但我无法想象它如何做到有用。投射到“AnyObject!”是一个非常奇怪的沮丧。 – 2015-02-10 20:15:36

+0

@RobNapier'obj [“getContactImagesByEmails”]'返回可选的,所以我解开它,并承诺'theData'不是'nil',否则它会在之前崩溃。我该如何写这个? – snaggs 2015-02-10 20:17:46

+0

你真正期望'command.arguments [0]'是什么类型?你期望它是一个字典吗?它是一个字典吗?什么类型是'命令?' – 2015-02-10 20:18:27

回答

2

我不知道这是否可以真正解决问题,但有一点冗余在2 if和以下let。它可以简单地写为:调用getImagesByEmailAsWmContactImage

if let results = WmSqliteImagesModel.getInstance.getImagesByEmailAsWmContactImage(contactImagesByEmails) as? Dictionary<String,AnyObject> { 
    ... 
} 

末时

if let contactImagesByEmails = obj["emails"] as? Array<String> { 
    results = WmSqliteImagesModel.getInstance.getImagesByEmailAsWmContactImage(contactImagesByEmails) as Dictionary<String,AnyObject> 
} 

此外,这将是更安全的可选的绑定和可选沮丧的结合,你肯定getInstance是一个属性,而不是方法?它不应该是:

if let results = WmSqliteImagesModel.getInstance().getImagesByEmailAsWmContactImage(contactImagesByEmails) as? Dictionary<String,AnyObject> { 
    ... 
} 
+0

'getInstance'是一个Singelton实例:'class var getInstance:WmSqliteImagesModel {0} { 静态让实例= WmSqliteImagesModel() } 回报Singleton.instance }' – snaggs 2015-02-10 20:22:27

+0

名称中的动词通常表明它的东西,即它是一种方法 - 我将其重命名为'instance'为清楚 - 但是这只是一个文体的东西 – Antonio 2015-02-10 20:28:12

1

也许尝试另一种方法来获取铸造值:

if let contactImagesByEmails = obj["emails"] as? [String] { 
     results = WmSqliteImagesModel.getInstance.getImagesByEmailAsWmContactImage(contactImagesByEmails) as Dictionary<String,AnyObject> 
    } 

我也想知道,如果你的崩溃是不是从你的原代码命名您的变量“阵列” ...

1

简化这一步一步与AnyObject(当然不是AnyObject!)更少的参考。编译器可能会通过一些非法的东西,因为当你开始拔出AnyObject时,你会说:“我确切知道我在做什么,不要检查它。”

你会想到这个代码是这样的:

let obj = command.arguments[0] 
if let contactImagesByEmails = obj["emails"] as? [String] { 
    results = WmSqliteImagesModel.getInstance.getImagesByEmailAsWmContactImage(array) as? [String: AnyObject] 
} 

到底results将是一个[String:AnyObject]?

这里的关键是,你应该摆脱许多引用到AnyObject尽可能地,并且您应该使用if-let-as?来确定这些类型是否符合您的期望。

事实上,command.arguments充满了各种类型的东西,你必须键入检查是非常危险的,并且是一个严重的设计问题的迹象。如果真的有几种类型的话,你应该使用enum而不是像[String:AnyObject]这样的随机事物进行类型检查。这就是枚举明确要求的。 (如果这是从ObjC桥接的;枚举在这里可能是不可能的,但即使在ObjC中,正确的答案也很少有一个填充了异构类型的NSArray。您在那里创建一个类来保存它们而不是枚举。)

+0

谢谢你的详细描述。我会尝试这种方法,并会接受。在cordova中,我从Javascript获得对象(命令)(无类型变量) – snaggs 2015-02-10 21:09:06

相关问题