Xcode 7 베타를 설치하고 빠른 코드를 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()
전화를 걸 었던 것처럼 오류를 잡아야하며 여기에서 여러 오류를 처리 try
하므로 다음과 같이 단일 do-catch 블록에서 여러 통화를 순차적으로 수행 할 수 있습니다 .
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()
}
답변
throws
Swift에서 선언 된 함수를 호출 할 때는 try
또는로 함수 호출 사이트에 주석을 달아야합니다 try!
. 예를 들어, 던지는 기능이 있다면 :
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
ed 코드 를 통해 발생해야합니다 .
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 문을 여러 개 가질 수 있습니다.
do {
try someFunctionThatThowsDifferentExceptions()
} catch MyErrorType.errorA {
// handle errorA
} catch MyErrorType.errorB {
// handle errorB
} catch {
// handle other errors
}
예외가있는 모범 사례에 대한 자세한 내용은 http://exceptionsafecode.com/을 참조하십시오 . C ++을 특별히 목표로했지만 Swift 예외 모델을 검토 한 후에 기본 사항이 Swift에도 적용된다고 생각합니다.
Swift 구문 및 오류 처리 모델에 대한 자세한 내용 은 Swift 프로그래밍 언어 (Swift 2 시험판) 책을 참조하십시오 .