快捷键2:可以抛出呼叫,但未将其标记为“ try”,并且未处理错误

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了快捷键2:可以抛出呼叫,但未将其标记为“ try”,并且未处理错误相关的知识,希望对你有一定的参考价值。

安装Xcode 7 beta版并将Swift代码转换为Swift 2之后,我遇到了一些我无法弄清楚的代码问题。我知道Swift 2是新手,所以我搜索并找出了答案,因为没有任何问题,我应该写一个问题。

这里是错误:

呼叫可以抛出,但未标记为“ try”,并且不会显示错误处理

代码:

func deleteAccountDetail()
        let entityDescription = NSEntityDescription.entityForName("AccountDetail", inManagedObjectContext: Context!)
        let request = NSFetchRequest()
        request.entity = entityDescription

        //The Line Below is where i expect the error
        let fetchedEntities = self.Context!.executeFetchRequest(request) as! [AccountDetail]

        for entity in fetchedEntities 
        self.Context!.deleteObject(entity)
        

        do 
            try self.Context!.save()
         catch _ 
        

    

快照:“在此处输入图像描述”

答案

[您必须像处理save()呼叫一样捕获错误,并且由于您正在此处处理多个错误,因此您可以在单个do-catch块中依次try多个调用,如下所示:

func deleteAccountDetail() 
    let entityDescription = NSEntityDescription.entityForName("AccountDetail", inManagedObjectContext: Context!)
    let request = NSFetchRequest()
    request.entity = entityDescription

    do 
        let fetchedEntities = try self.Context!.executeFetchRequest(request) as! [AccountDetail]

        for entity in fetchedEntities 
            self.Context!.deleteObject(entity)
        

        try self.Context!.save()
     catch 
        print(error)
    

或@ bames53在下面的注释中指出,通常更好的做法是不要在引发错误的地方捕获错误。您可以将方法标记为throws,然后将其标记为try以调用该方法。例如:

func deleteAccountDetail() throws 
    let entityDescription = NSEntityDescription.entityForName("AccountDetail", inManagedObjectContext: Context!)
    let request = NSFetchRequest()

    request.entity = entityDescription

    let fetchedEntities = try Context.executeFetchRequest(request) as! [AccountDetail]

    for entity in fetchedEntities 
        self.Context!.deleteObject(entity)
    

    try self.Context!.save()

另一答案

[在Swift中调用用throws声明的函数时,必须用trytry!注释函数调用位置。例如,给定一个throwing函数:

func willOnlyThrowIfTrue(value: Bool) throws 
  if value  throw someError 

此函数可以这样称呼:

func foo(value: Bool) throws 
  try willOnlyThrowIfTrue(value)

这里我们用try注释了该调用,该调用使读者意识到此函数可能引发异常,并且以下任何代码行都可能不会执行。我们还必须用throws注释此函数,因为此函数可能会引发异常(即,当willOnlyThrowIfTrue()引发时,foo会自动向上抛出异常。

如果要调用一个声明为可能抛出的函数,但由于给它正确的输入而不会在情况下抛出该异常,则可以使用try!

func bar() 
  try! willOnlyThrowIfTrue(false)

这样,当您确保不会抛出代码时,您不必放入额外的样板代码来禁用异常传播。

[try!在运行时被强制执行:如果您使用try!并且该函数确实抛出了,则程序的执行将因运行时错误而终止。

大多数异常处理代码应类似于上面:要么在发生异常时简单地向上传播异常,要么设置条件以排除可能的异常。代码中对其他资源的任何清理都应通过对象销毁(即deinit())或有时通过defer编码来进行。

func baz(value: Bool) throws 

  var filePath = NSBundle.mainBundle().pathForResource("theFile", ofType:"txt")
  var data = NSData(contentsOfFile:filePath)

  try willOnlyThrowIfTrue(value)

  // data and filePath automatically cleaned up, even when an exception occurs.

如果出于某种原因,您有需要运行的清理代码但不在deinit()函数中,则可以使用defer

func qux(value: Bool) throws 
  defer 
    print("this code runs when the function exits, even when it exits by an exception")
  

  try willOnlyThrowIfTrue(value)


大多数处理异常的代码只是使它们向上传播给调用者,并通过deinit()defer进行清除。这是因为大多数代码都不知道如何处理错误。它知道出了什么问题,但是没有足够的信息来了解一些更高级别的代码正在试图做什么,以便知道如何处理该错误。它不知道向用户显示对话框是否合适,或者是否应该重试,或者其他合适的方法。

但是,更高级别的代码应该确切知道在发生任何错误的情况下该怎么做。因此,异常允许特定错误从最初发生的地方冒出来,到可以处理的地方。

通过catch语句处理异常。

func quux(value: Bool) 
  do 
    try willOnlyThrowIfTrue(value)
   catch 
    // handle error
  

您可以有多个catch语句,每个catch语句都捕获不同类型的异常。

  do 
    try someFunctionThatThowsDifferentExceptions()
   catch MyErrorType.errorA 
    // handle errorA
   catch MyErrorType.errorB 
    // handle errorB
   catch 
    // handle other errors
  

有关例外的最佳做法的更多详细信息,请参见http://exceptionsafecode.com/。它专门针对C ++,但是在研究了Swift异常模型之后,我相信这些基础知识也同样适用于Swift。

有关Swift语法和错误处理模型的详细信息,请参见The Swift Programming Language (Swift 2 Prerelease)

另一答案

已接受答案的快速5.1

用法:

self.mytextView.attributedText = identifyTextContent(text_string)

功能:

func identifyTextContent(_ txtStr: String?) -> NSMutableAttributedString 

        let attributedString = NSMutableAttributedString(string: txtvwstr ?? "")
        let textAttachment = NSTextAttachment()
        var detector: NSDataDetector? = nil
        do 
            detector = try NSDataDetector(types: NSTextCheckingResult.CheckingType.link.rawValue)
         catch 
        
        detector?.enumerateMatches(in: txtvwstr ?? "", options: [], range: NSRange(location: 0, length: txtvwstr?.count ?? 0), using:  result, flags, stop in
            if let result = result 
                print("Values: \(result)")
            
            if result?.resultType == .link 
                if let URL = result?.url 
                    print("matched: \(URL)")
                
                ////You can use any library to download the image from detected url.*/
                var data: Data? = nil
                if let URL = result?.url 
                    do 
                    data = try Data(contentsOf: URL)
                     catch 
                        print(error)
                    
                
                var img: UIImage? = nil
                if let data = data 
                    img = UIImage(data: data)
        //**Here You can adjust image size as well using CGSize(width, height)**

                
                textAttachment.image = img
                let attrStringWithImage = NSAttributedString(attachment: textAttachment)
                if let range = result?.range 
                    attributedString.replaceCharacters(in: range, with: attrStringWithImage)
                
            
        )

        return attributedString
    

以上是关于快捷键2:可以抛出呼叫,但未将其标记为“ try”,并且未处理错误的主要内容,如果未能解决你的问题,请参考以下文章

Android NDK 创建可执行文件但未将其推送到设备上 (Eclipse)

Swift 2 jSON Call 可以抛出,但没有用 try 标记

调用可以抛出,但它没有标记为'try'并且没有处理错误:NSRegularExpression

Swift 2.1 - 调用可以抛出,但它没有用'try'标记并且错误没有被处理

Swift 2:调用可以抛出,但它没有用'try'标记并且错误没有被处理

“调用可以抛出,但它没有用'try'标记并且错误没有处理“[重复]