尝试 - 抛出 IBAction - xCode 7
try - throws in IBAction - xCode 7
我对新的 "throws" - "try" 参数有疑问。
添加这些词时出现错误,因此我在 IBAction 函数的末尾添加了 "throws"。
@IBAction func loginButtonPressed(sender: AnyObject)throws {//code here}
在里面我正在做一些无关紧要的事情,然后是这个:
let jsonData:NSDictionary = try NSJSONSerialization.JSONObjectWithData(urlData!, options:NSJSONReadingOptions.MutableContainers ) as! NSDictionary
之后没有错误,但是当我 运行 应用程序并单击按钮时,应用程序崩溃并显示代码
2015-06-15 10:43:11.374 BottLED[7283:1175818] -[BottLED.loginViewController loginButtonPressed:]: unrecognized selector sent to instance 0x7fee28da7d20
2015-06-15 10:43:11.381 BottLED[7283:1175818] * Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[BottLED.loginViewController loginButtonPressed:]: unrecognized selector sent to instance 0x7fee28da7d20'
* First throw call stack:
(
0 CoreFoundation 0x000000010d67c885 exceptionPreprocess + 165
1 libobjc.A.dylib 0x000000010cd0edf1 objc_exception_throw + 48
2 CoreFoundation 0x000000010d684b5d -[NSObject(NSObject) doesNotRecognizeSelector:] + 205
3 CoreFoundation 0x000000010d5d1e3a ___forwarding_ + 970
4 CoreFoundation 0x000000010d5d19e8 _CF_forwarding_prep_0 + 120
5 UIKit 0x000000010dc46257 -[UIApplication sendAction:to:from:forEvent:] + 125
6 UIKit 0x000000010dc461b2 -[UIApplication sendAction:toTarget:fromSender:forEvent:] + 79
7 UIKit 0x000000010dda1422 -[UIControl sendAction:to:forEvent:] + 67
8 UIKit 0x000000010dda16c6 -[UIControl _sendActionsForEvents:withEvent:] + 272
9 UIKit 0x000000010dda08a9 -[UIControl touchesEnded:withEvent:] + 599
10 UIKit 0x000000010dcacbe8 -[UIWindow _sendTouchesForEvent:] + 835
11 UIKit 0x000000010dcad7d6 -[UIWindow sendEvent:] + 865
12 UIKit 0x000000010dc62705 -[UIApplication sendEvent:] + 263
13 UIKit 0x000000010dc3f5df _UIApplicationHandleEventQueue + 6031
14 CoreFoundation 0x000000010d5a70f1 CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION + 17
15 CoreFoundation 0x000000010d59ceac __CFRunLoopDoSources0 + 556
16 CoreFoundation 0x000000010d59c363 __CFRunLoopRun + 867
17 CoreFoundation 0x000000010d59bd78 CFRunLoopRunSpecific + 488
18 GraphicsServices 0x0000000111fdebca GraphicsServices + 52170
19 UIKit 0x000000010dc4479b UIApplicationMain + 171
20 BottLED 0x000000010c7cb9ad main + 109
21 libdyld.dylib 0x000000011029ca05 libdyld.dylib + 10757
22 ??? 0x0000000000000001 0x0 + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException
(lldb)
当我做一些断点并删除 "throws" 时,应用程序不会崩溃。我现在真的不知道怎么办。。希望有人能帮帮我!
完整代码为:
@IBAction func loginButtonPressed(sender: AnyObject)throws {
var name:NSString = textFieldName.text!
let pass:NSString = textFieldPw.text!
if ( name.isEqualToString("") || pass.isEqualToString("") ) {
let loginFailed = UIAlertView(title: "Failed to Signup",
message: "Please fill in all Textfields",
delegate: nil,
cancelButtonTitle: "OK")
loginFailed.show()
} else {
let post:NSString = "username=\(name)&password=\(pass)"
NSLog("PostData: %@",post);
let url:NSURL = NSURL(string: "my url")!
let postData:NSData = post.dataUsingEncoding(NSASCIIStringEncoding)!
let postLength:NSString = String( postData.length )
let request:NSMutableURLRequest = NSMutableURLRequest(URL: url)
request.HTTPMethod = "POST"
request.HTTPBody = postData
request.setValue(postLength as String, forHTTPHeaderField: "Content-Length")
request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
request.setValue("application/json", forHTTPHeaderField: "Accept")
var reponseError: NSError?
var response: NSURLResponse?
var urlData: NSData?
do {
urlData = try NSURLConnection.sendSynchronousRequest(request, returningResponse:&response)
} catch let error as NSError {
reponseError = error
urlData = nil
}
if ( urlData != nil ) {
let res = response as! NSHTTPURLResponse!;
NSLog("Response code: %ld", res.statusCode);
if (res.statusCode >= 200 && res.statusCode < 300)
{
let responseData:NSString = NSString(data:urlData!, encoding:NSUTF8StringEncoding)!
NSLog("Response ==> %@", responseData);
let jsonData:NSDictionary = try NSJSONSerialization.JSONObjectWithData(urlData!, options:NSJSONReadingOptions.MutableContainers ) as! NSDictionary
let success:NSInteger = jsonData.valueForKey("success") as! NSInteger
//[jsonData[@"success"] integerValue];
NSLog("Success: %ld", success);
if(success == 1)
{
在 Obj-C 中 throws
是 Obj-C error: (NSError **)error
参数的语法糖。
当你在方法中添加throws
时,它是在偷偷添加参数。您的方法将不再是 loginButtonPressed:
,它将是 loginButtonPressed:error:
(至少对于 Obj-C)。然而,当事件被处理时,系统仍然会寻找方法 loginButtonPressed:
因为这就是事件在 XIB 中的连接方式。该方法不再存在,因此应用程序将崩溃并显示 unrecognized selector sent to instance
。
解决方案:不要在动作处理程序中使用throws
,它违反了方法的约定,因为系统不希望在那里抛出任何东西.在您的操作处理程序中捕获所有错误。
do {
urlData = try NSURLConnection.sendSynchronousRequest(request, returningResponse:&response)
} catch let error as NSError {
reponseError = error
urlData = nil
} catch {
// Catch all error-handling
urlData = nil
}
没有什么可以捕获错误。您需要从按钮 IBAction 中取出 throws 方法。
从 IBAction 中删除抛出并创建一个新方法。然后尝试捕获方法中的错误。无论哪种方式,都不要从 IBAction 中抛出。
我对新的 "throws" - "try" 参数有疑问。
添加这些词时出现错误,因此我在 IBAction 函数的末尾添加了 "throws"。
@IBAction func loginButtonPressed(sender: AnyObject)throws {//code here}
在里面我正在做一些无关紧要的事情,然后是这个:
let jsonData:NSDictionary = try NSJSONSerialization.JSONObjectWithData(urlData!, options:NSJSONReadingOptions.MutableContainers ) as! NSDictionary
之后没有错误,但是当我 运行 应用程序并单击按钮时,应用程序崩溃并显示代码
2015-06-15 10:43:11.374 BottLED[7283:1175818] -[BottLED.loginViewController loginButtonPressed:]: unrecognized selector sent to instance 0x7fee28da7d20 2015-06-15 10:43:11.381 BottLED[7283:1175818] * Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[BottLED.loginViewController loginButtonPressed:]: unrecognized selector sent to instance 0x7fee28da7d20' * First throw call stack: ( 0 CoreFoundation 0x000000010d67c885 exceptionPreprocess + 165 1 libobjc.A.dylib 0x000000010cd0edf1 objc_exception_throw + 48 2 CoreFoundation 0x000000010d684b5d -[NSObject(NSObject) doesNotRecognizeSelector:] + 205 3 CoreFoundation 0x000000010d5d1e3a ___forwarding_ + 970 4 CoreFoundation 0x000000010d5d19e8 _CF_forwarding_prep_0 + 120 5 UIKit 0x000000010dc46257 -[UIApplication sendAction:to:from:forEvent:] + 125 6 UIKit 0x000000010dc461b2 -[UIApplication sendAction:toTarget:fromSender:forEvent:] + 79 7 UIKit 0x000000010dda1422 -[UIControl sendAction:to:forEvent:] + 67 8 UIKit 0x000000010dda16c6 -[UIControl _sendActionsForEvents:withEvent:] + 272 9 UIKit 0x000000010dda08a9 -[UIControl touchesEnded:withEvent:] + 599 10 UIKit 0x000000010dcacbe8 -[UIWindow _sendTouchesForEvent:] + 835 11 UIKit 0x000000010dcad7d6 -[UIWindow sendEvent:] + 865 12 UIKit 0x000000010dc62705 -[UIApplication sendEvent:] + 263 13 UIKit 0x000000010dc3f5df _UIApplicationHandleEventQueue + 6031 14 CoreFoundation 0x000000010d5a70f1 CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION + 17 15 CoreFoundation 0x000000010d59ceac __CFRunLoopDoSources0 + 556 16 CoreFoundation 0x000000010d59c363 __CFRunLoopRun + 867 17 CoreFoundation 0x000000010d59bd78 CFRunLoopRunSpecific + 488 18 GraphicsServices 0x0000000111fdebca GraphicsServices + 52170 19 UIKit 0x000000010dc4479b UIApplicationMain + 171 20 BottLED 0x000000010c7cb9ad main + 109 21 libdyld.dylib 0x000000011029ca05 libdyld.dylib + 10757 22 ??? 0x0000000000000001 0x0 + 1 ) libc++abi.dylib: terminating with uncaught exception of type NSException (lldb)
当我做一些断点并删除 "throws" 时,应用程序不会崩溃。我现在真的不知道怎么办。。希望有人能帮帮我!
完整代码为:
@IBAction func loginButtonPressed(sender: AnyObject)throws {
var name:NSString = textFieldName.text!
let pass:NSString = textFieldPw.text!
if ( name.isEqualToString("") || pass.isEqualToString("") ) {
let loginFailed = UIAlertView(title: "Failed to Signup",
message: "Please fill in all Textfields",
delegate: nil,
cancelButtonTitle: "OK")
loginFailed.show()
} else {
let post:NSString = "username=\(name)&password=\(pass)"
NSLog("PostData: %@",post);
let url:NSURL = NSURL(string: "my url")!
let postData:NSData = post.dataUsingEncoding(NSASCIIStringEncoding)!
let postLength:NSString = String( postData.length )
let request:NSMutableURLRequest = NSMutableURLRequest(URL: url)
request.HTTPMethod = "POST"
request.HTTPBody = postData
request.setValue(postLength as String, forHTTPHeaderField: "Content-Length")
request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
request.setValue("application/json", forHTTPHeaderField: "Accept")
var reponseError: NSError?
var response: NSURLResponse?
var urlData: NSData?
do {
urlData = try NSURLConnection.sendSynchronousRequest(request, returningResponse:&response)
} catch let error as NSError {
reponseError = error
urlData = nil
}
if ( urlData != nil ) {
let res = response as! NSHTTPURLResponse!;
NSLog("Response code: %ld", res.statusCode);
if (res.statusCode >= 200 && res.statusCode < 300)
{
let responseData:NSString = NSString(data:urlData!, encoding:NSUTF8StringEncoding)!
NSLog("Response ==> %@", responseData);
let jsonData:NSDictionary = try NSJSONSerialization.JSONObjectWithData(urlData!, options:NSJSONReadingOptions.MutableContainers ) as! NSDictionary
let success:NSInteger = jsonData.valueForKey("success") as! NSInteger
//[jsonData[@"success"] integerValue];
NSLog("Success: %ld", success);
if(success == 1)
{
在 Obj-C 中 throws
是 Obj-C error: (NSError **)error
参数的语法糖。
当你在方法中添加throws
时,它是在偷偷添加参数。您的方法将不再是 loginButtonPressed:
,它将是 loginButtonPressed:error:
(至少对于 Obj-C)。然而,当事件被处理时,系统仍然会寻找方法 loginButtonPressed:
因为这就是事件在 XIB 中的连接方式。该方法不再存在,因此应用程序将崩溃并显示 unrecognized selector sent to instance
。
解决方案:不要在动作处理程序中使用throws
,它违反了方法的约定,因为系统不希望在那里抛出任何东西.在您的操作处理程序中捕获所有错误。
do {
urlData = try NSURLConnection.sendSynchronousRequest(request, returningResponse:&response)
} catch let error as NSError {
reponseError = error
urlData = nil
} catch {
// Catch all error-handling
urlData = nil
}
没有什么可以捕获错误。您需要从按钮 IBAction 中取出 throws 方法。
从 IBAction 中删除抛出并创建一个新方法。然后尝试捕获方法中的错误。无论哪种方式,都不要从 IBAction 中抛出。