try — бросает IBAction — xCode 7

У меня проблема с новыми параметрами "throws" - "try".

Я получаю сообщение об ошибке, чтобы добавить эти слова, поэтому я добавил «броски» в конце функции IBAction.

@IBAction func loginButtonPressed(sender: AnyObject)throws {//code here}

Внутри я занимаюсь какими-то не относящимися к делу вещами, а затем это:

let jsonData:NSDictionary = try NSJSONSerialization.JSONObjectWithData(urlData!, options:NSJSONReadingOptions.MutableContainers ) as! NSDictionary

После этого ошибок нет, но когда я запускаю приложение и нажимаю на кнопку, приложение вылетает с кодом

когда я делаю некоторые точки останова и удаляю «броски», приложение не падает. Я действительно не знаю, что теперь делать .. Я надеюсь, что кто-то может мне помочь!

Полный код:

В Obj-C

@IBAction func loginButtonPressed(sender: AnyObject)throws {//code here}
является синтаксическим сахаром для параметра Obj-C
let jsonData:NSDictionary = try NSJSONSerialization.JSONObjectWithData(urlData!, options:NSJSONReadingOptions.MutableContainers ) as! NSDictionary
.

@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)
                    {

person Luke Pistrol    schedule 15.06.2015    source источник
comment
нет, не знаю. Я опубликую весь код через минуту   -  person Fogmeister    schedule 15.06.2015
comment
И как мне это сделать? Не могли бы вы привести пример?   -  person Luke Pistrol    schedule 15.06.2015


Ответы (2)


Когда вы добавляете throws к методу, он тайно добавляет параметр. Ваш метод больше не будет loginButtonPressed:, он будет loginButtonPressed:error: (по крайней мере, для Obj-C). Однако при обработке события система по-прежнему будет искать метод loginButtonPressed:, потому что именно так событие было связано с XIB. Метода больше нет, поэтому приложение вылетает с ошибкой unrecognized selector sent to instance.

Решение: не используйте throws в обработчиках действий, это нарушает контракт метода, потому что система не ожидает, что туда будет что-то выброшено. Перехватывайте все ошибки внутри вашего обработчика действий.

Ничто не может поймать ошибку. Вам нужно вывести метод throws из кнопки IBAction.

do {
    urlData = try NSURLConnection.sendSynchronousRequest(request, returningResponse:&response)
} catch let error as NSError {
    reponseError = error
    urlData = nil
} catch {
   // Catch all error-handling
    urlData = nil
}
person Sulthan    schedule 15.06.2015
comment
@LukePistrol Добавлен пример, как отловить все ошибки. - person Luke Pistrol; 15.06.2015
comment
Ok. и как использовать это для let jsonData:NSDictionary = try NSJSONSerialization.JSONObjectWithData(urlData!, options:NSJSONReadingOptions.MutableContainers) as! NSDictionary - person Sulthan; 15.06.2015
comment
@LukePisttrol Точно так же, просто всегда добавляйте этот _1_ в качестве последнего обработчика ошибок. Вы можете поместить утверждение там, если хотите. - person Luke Pistrol; 15.06.2015
comment
2015-06-15 10:43:11.374 BottLED[7283:1175818] -[BottLED.loginViewController loginButtonPressed:]: нераспознанный селектор отправлен экземпляру 0x7fee28da7d20 2015-06-15 10:43:11.381 BottLED[7283:1175818] * Завершение работы приложения из-за необработанного исключения 'NSInvalidArgumentException', причина: '-[BottLED.loginViewController loginButtonPressed:]: нераспознанный селектор отправлен экземпляру 0x7fee28da7d20' 1 libobjc.A.dylib 0x000000010cd0edf1 objc_exception_throw + 48 2 CoreFoundation 0x000000010d684b5d - [NSObject (NSObject) doesNotRecognizeSelector:] + 205 3 CoreFoundation 0x000000010d5d1e3a ___ пересылка _ + 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 0x000 0x0da [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 разливают в бутылки 0x000000010c7cb9ad основной + 109 21 libdyld.dylib 0x000000011029ca05 libdyld. дилиб + 10757 22 ? ?? 0x0000000000000001 0x0 + 1 ) libc++abi.dylib: завершение с необработанным исключением типа NSException (lldb) - person Sulthan; 15.06.2015

Удалите броски из IBAction и создайте новый метод. Затем попробуйте поймать ошибку в методе. В любом случае, не выбрасывайте из IBAction.

Какой у вас полный код? Вам нужно обернуть попытку в блок do-catch. Вы делаете это?

person Fogmeister    schedule 15.06.2015