2017-09-18 11 views
1

にERROR``にキャストすることはできません経由でカスタム `ERROR`を送信:私はようNotificationCenter経由でこのMyErrorを送りたいスウィフト3は、 `Notification`私はカスタムエラー列挙型を持って観察方法

enum MyError: LocalizedError { 
    case runtimeError(String) 

    public var errorDescription: String? { 
     switch self { 
     case .runtimeError(let message): 
      return message 
     } 
    } 
} 

Notificationの対象例:

NotificationCenter.default.post(name: .errorMessage, object: MyError.runtimeError("Some error message")) 

それは私のメソッドに到着したときに問題が、Errorにオブジェクトをキャストすることはすなわちnilを返す失敗します

@objc private func errorMessage(notification: Notification) { 
    guard let error = notification.object as? Error else { 
     return 
    } 
    ... 
} 

私は、オブジェクトをキャストすると、デバッガで演奏し、それがMyErrorにキャストすることができますし、つまり、これが非nilの(notification.object as? MyError) as? ErrorあるErrorにdowncastedすることができます。

IはMyErrorためenumの代わりstructを使用する場合、それは同じ(Errorに即ちキャストnilである)が、完全にclass作品を使用して動作します。これはSwift言語のバグですか、何か不足していますか?

+1

これは、MyErrorがNSObjectから派生する必要があるためです(つまり、'@ objc')をネイティブのSwiftの' enum'と 'struct'を除外する' Notification'のオブジェクトとして渡します。私は簡単に証明することはできません。 –

+0

'object:MyError.runtimeError("何らかのエラーメッセージ ")をNSError'として渡すと動作しますか? –

+0

@MartinR問題を修正したが、このような状況で 'MyError'をキャストするとエラーが起こりやすく、以下の@ CharlesSrstkaの答えが優先されます。 – shelll

答えて

1

これは基本的にSwiftのBSのためです。< - > Objective-Cブリッジングマジックnotification.objectによって返された値でダイナミックタイプをチェックすると、実際にエラータイプではなく、_SwiftValueと呼ばれる不透明なタイプが表示されます。これはクラスを取るObjective-C APIのSwift値タイプをラップするために使用されます。これは、時には必ずしも意味をなさないと思われる理由のために、時にはスパナを作品に投げることがあります。

とにかく、これはそれを修正します:

guard let error = notification.object as AnyObject as? Error else { 
    return 
} 

はEDIT:あなたはおそらく、なぜ地球上でこの問題を迷っています。まあ、私は絶対的な権威であると主張するつもりはない。しかし、コンパイラが何をしているのか解明しようとすると、分解を見ることができます。そして、これは私が見たものである。

func foo(_ notification: Notification) { 
    let error = notification.object as? Error 
} 

のために私が手:

func foo(_ notification: Notification) { 
    let error = notification.object as AnyObject as? Error 
} 

のために私が手

totalbs`foo(_:): 
    0x100002550 <+0>: pushq %rbp 
    0x100002551 <+1>: movq %rsp, %rbp 
    0x100002554 <+4>: subq $0xb0, %rsp 
    0x10000255b <+11>: leaq -0x30(%rbp), %rax 
    0x10000255f <+15>: movq %rdi, -0x8(%rbp) 
-> 0x100002563 <+19>: movq %rdi, %rcx 
    0x100002566 <+22>: addq $0x8, %rcx 
    0x10000256a <+26>: movq %rcx, %rdx 
    0x10000256d <+29>: testb $0x1, 0x28(%rdi) 
    0x100002571 <+33>: movq %rdi, -0x48(%rbp) 
    0x100002575 <+37>: movq %rcx, -0x50(%rbp) 
    0x100002579 <+41>: movq %rax, -0x58(%rbp) 
    0x10000257d <+45>: movq %rdx, -0x60(%rbp) 
    0x100002581 <+49>: jne 0x1000025b5    ; <+101> at main.swift 
    0x100002583 <+51>: movq -0x60(%rbp), %rax 
    0x100002587 <+55>: movq 0x18(%rax), %rcx 
    0x10000258b <+59>: movq -0x58(%rbp), %rdx 
    0x10000258f <+63>: movq %rcx, 0x18(%rdx) 
    0x100002593 <+67>: movq -0x8(%rcx), %rsi 
    0x100002597 <+71>: movq %rdx, %rdi 
    0x10000259a <+74>: movq %rsi, -0x68(%rbp) 
    0x10000259e <+78>: movq %rax, %rsi 
    0x1000025a1 <+81>: movq %rcx, %rdx 
    0x1000025a4 <+84>: movq -0x68(%rbp), %rcx 
    0x1000025a8 <+88>: callq *0x8(%rcx) 
    0x1000025ab <+91>: movb $0x0, -0x10(%rbp) 
    0x1000025af <+95>: movq %rax, -0x70(%rbp) 
    0x1000025b3 <+99>: jmp 0x1000025cc    ; <+124> at main.swift:17 
    0x1000025b5 <+101>: movl $0x21, %eax 
    0x1000025ba <+106>: movl %eax, %edx 
    0x1000025bc <+108>: leaq -0x30(%rbp), %rcx 
    0x1000025c0 <+112>: movq -0x50(%rbp), %rsi 
    0x1000025c4 <+116>: movq %rcx, %rdi 
    0x1000025c7 <+119>: callq 0x10051b18c    ; symbol stub for: memcpy 
    0x1000025cc <+124>: movb -0x10(%rbp), %al 
    0x1000025cf <+127>: xorb $-0x1, %al 
    0x1000025d1 <+129>: testb $0x1, %al 
    0x1000025d3 <+131>: jne 0x1000025ec    ; <+156> at main.swift 
    0x1000025d5 <+133>: testb $0x1, -0x10(%rbp) 
    0x1000025d9 <+137>: jne 0x1000025e7    ; <+151> at main.swift:17 
    0x1000025db <+139>: leaq -0x30(%rbp), %rax 
    0x1000025df <+143>: movq %rax, %rdi 
    0x1000025e2 <+146>: callq 0x1000029c0    ; __swift_destroy_boxed_opaque_existential_0 at main.swift 
    0x1000025e7 <+151>: jmp 0x1000026d0    ; <+384> at main.swift 
    0x1000025ec <+156>: leaq -0x40(%rbp), %rax 
    0x1000025f0 <+160>: leaq -0x30(%rbp), %rcx 
    0x1000025f4 <+164>: movq %rax, -0x78(%rbp) 
    0x1000025f8 <+168>: movq %rcx, -0x80(%rbp) 
    0x1000025fc <+172>: callq 0x100002a80    ; type metadata accessor for Any at main.swift 
    0x100002601 <+177>: movq %rax, -0x88(%rbp) 
    0x100002608 <+184>: callq 0x100002b00    ; type metadata accessor for Swift.Error at main.swift 
    0x10000260d <+189>: movl $0x6, %edx 
    0x100002612 <+194>: movl %edx, %r8d 
    0x100002615 <+197>: movq -0x78(%rbp), %rdi 
    0x100002619 <+201>: movq -0x80(%rbp), %rsi 
    0x10000261d <+205>: movq -0x88(%rbp), %rdx 
    0x100002624 <+212>: movq %rax, %rcx 
    0x100002627 <+215>: callq 0x100002b60    ; swift_rt_swift_dynamicCast 
    0x10000262c <+220>: testb $0x1, %al 
    0x10000262e <+222>: jne 0x100002632    ; <+226> at main.swift:17 
    0x100002630 <+224>: jmp 0x10000263f    ; <+239> at main.swift 
    0x100002632 <+226>: movq -0x40(%rbp), %rax 
    0x100002636 <+230>: movq %rax, -0x90(%rbp) 
    0x10000263d <+237>: jmp 0x10000264a    ; <+250> at main.swift:17 
    0x10000263f <+239>: xorl %eax, %eax 
    0x100002641 <+241>: movl %eax, %ecx 
    0x100002643 <+243>: movq %rcx, -0x90(%rbp) 
    0x10000264a <+250>: movq -0x90(%rbp), %rax 
    0x100002651 <+257>: movq %rax, -0x98(%rbp) 
    0x100002658 <+264>: movq -0x98(%rbp), %rax 
    0x10000265f <+271>: movq %rax, -0x38(%rbp) 
    0x100002663 <+275>: movq %rax, %rdi 
    0x100002666 <+278>: callq 0x100509080    ; swift_errorRelease 
    0x10000266b <+283>: movq -0x48(%rbp), %rax 
    0x10000266f <+287>: movq (%rax), %rdi 
    0x100002672 <+290>: callq 0x10051b20a    ; symbol stub for: objc_release 
    0x100002677 <+295>: movq -0x48(%rbp), %rax 
    0x10000267b <+299>: addq $0x8, %rax 
    0x10000267f <+303>: movq -0x48(%rbp), %rdi 
    0x100002683 <+307>: testb $0x1, 0x28(%rdi) 
    0x100002687 <+311>: movq %rax, -0xa0(%rbp) 
    0x10000268e <+318>: jne 0x10000269f    ; <+335> at main.swift:18 
    0x100002690 <+320>: movq -0xa0(%rbp), %rax 
    0x100002697 <+327>: movq %rax, %rdi 
    0x10000269a <+330>: callq 0x1000029c0    ; __swift_destroy_boxed_opaque_existential_0 at main.swift 
    0x10000269f <+335>: movq -0x48(%rbp), %rax 
    0x1000026a3 <+339>: addq $0x30, %rax 
    0x1000026a7 <+343>: movq -0x48(%rbp), %rcx 
    0x1000026ab <+347>: testb $0x1, 0x38(%rcx) 
    0x1000026af <+351>: movq %rax, -0xa8(%rbp) 
    0x1000026b6 <+358>: jne 0x1000026c7    ; <+375> at main.swift:18 
    0x1000026b8 <+360>: movq -0xa8(%rbp), %rax 
    0x1000026bf <+367>: movq (%rax), %rdi 
    0x1000026c2 <+370>: callq 0x100001bb0    ; outlined copy of Swift._VariantDictionaryBuffer with unmangled suffix ".1" 
    0x1000026c7 <+375>: addq $0xb0, %rsp 
    0x1000026ce <+382>: popq %rbp 
    0x1000026cf <+383>: retq 
    0x1000026d0 <+384>: xorl %eax, %eax 
    0x1000026d2 <+386>: movl %eax, %ecx 
    0x1000026d4 <+388>: movq %rcx, -0x98(%rbp) 
    0x1000026db <+395>: jmp 0x100002658    ; <+264> at main.swift 

に対し:

totalbs`foo(_:): 
    0x1000024e0 <+0>: pushq %rbp 
    0x1000024e1 <+1>: movq %rsp, %rbp 
    0x1000024e4 <+4>: pushq %r13 
    0x1000024e6 <+6>: subq $0xb8, %rsp 
    0x1000024ed <+13>: leaq -0x38(%rbp), %rax 
    0x1000024f1 <+17>: movq %rdi, -0x10(%rbp) 
-> 0x1000024f5 <+21>: movq %rdi, %rcx 
    0x1000024f8 <+24>: addq $0x8, %rcx 
    0x1000024fc <+28>: movq %rcx, %rdx 
    0x1000024ff <+31>: testb $0x1, 0x28(%rdi) 
    0x100002503 <+35>: movq %rdi, -0x58(%rbp) 
    0x100002507 <+39>: movq %rcx, -0x60(%rbp) 
    0x10000250b <+43>: movq %rax, -0x68(%rbp) 
    0x10000250f <+47>: movq %rdx, -0x70(%rbp) 
    0x100002513 <+51>: jne 0x100002547    ; <+103> at main.swift 
    0x100002515 <+53>: movq -0x70(%rbp), %rax 
    0x100002519 <+57>: movq 0x18(%rax), %rcx 
    0x10000251d <+61>: movq -0x68(%rbp), %rdx 
    0x100002521 <+65>: movq %rcx, 0x18(%rdx) 
    0x100002525 <+69>: movq -0x8(%rcx), %rsi 
    0x100002529 <+73>: movq %rdx, %rdi 
    0x10000252c <+76>: movq %rsi, -0x78(%rbp) 
    0x100002530 <+80>: movq %rax, %rsi 
    0x100002533 <+83>: movq %rcx, %rdx 
    0x100002536 <+86>: movq -0x78(%rbp), %rcx 
    0x10000253a <+90>: callq *0x8(%rcx) 
    0x10000253d <+93>: movb $0x0, -0x18(%rbp) 
    0x100002541 <+97>: movq %rax, -0x80(%rbp) 
    0x100002545 <+101>: jmp 0x10000255e    ; <+126> at main.swift:17 
    0x100002547 <+103>: movl $0x21, %eax 
    0x10000254c <+108>: movl %eax, %edx 
    0x10000254e <+110>: leaq -0x38(%rbp), %rcx 
    0x100002552 <+114>: movq -0x60(%rbp), %rsi 
    0x100002556 <+118>: movq %rcx, %rdi 
    0x100002559 <+121>: callq 0x10051b18c    ; symbol stub for: memcpy 
    0x10000255e <+126>: callq 0x100002a20    ; type metadata accessor for Swift.Optional<Any> at main.swift 
    0x100002563 <+131>: leaq -0x38(%rbp), %rcx 
    0x100002567 <+135>: movq %rax, %rdi 
    0x10000256a <+138>: movq %rcx, %r13 
    0x10000256d <+141>: callq 0x10029cfe0    ; Swift.Optional._bridgeToObjectiveC() -> Swift.AnyObject 
    0x100002572 <+146>: testb $0x1, -0x18(%rbp) 
    0x100002576 <+150>: movq %rax, -0x88(%rbp) 
    0x10000257d <+157>: jne 0x10000258b    ; <+171> at main.swift 
    0x10000257f <+159>: leaq -0x38(%rbp), %rax 
    0x100002583 <+163>: movq %rax, %rdi 
    0x100002586 <+166>: callq 0x100002960    ; __swift_destroy_boxed_opaque_existential_0 at main.swift 
    0x10000258b <+171>: leaq -0x40(%rbp), %rax 
    0x10000258f <+175>: leaq -0x48(%rbp), %rcx 
    0x100002593 <+179>: movq -0x88(%rbp), %rdx 
    0x10000259a <+186>: movq %rdx, -0x40(%rbp) 
    0x10000259e <+190>: movq %rcx, -0x90(%rbp) 
    0x1000025a5 <+197>: movq %rax, -0x98(%rbp) 
    0x1000025ac <+204>: callq 0x100002ae0    ; type metadata accessor for Swift.AnyObject at main.swift 
    0x1000025b1 <+209>: movq %rax, -0xa0(%rbp) 
    0x1000025b8 <+216>: callq 0x100002b30    ; type metadata accessor for Swift.Error at main.swift 
    0x1000025bd <+221>: movl $0x6, %esi 
    0x1000025c2 <+226>: movl %esi, %r8d 
    0x1000025c5 <+229>: movq -0x90(%rbp), %rdi 
    0x1000025cc <+236>: movq -0x98(%rbp), %rsi 
    0x1000025d3 <+243>: movq -0xa0(%rbp), %rdx 
    0x1000025da <+250>: movq %rax, %rcx 
    0x1000025dd <+253>: callq 0x100002b90    ; swift_rt_swift_dynamicCast 
    0x1000025e2 <+258>: testb $0x1, %al 
    0x1000025e4 <+260>: jne 0x1000025e8    ; <+264> at main.swift:17 
    0x1000025e6 <+262>: jmp 0x1000025f5    ; <+277> at main.swift 
    0x1000025e8 <+264>: movq -0x48(%rbp), %rax 
    0x1000025ec <+268>: movq %rax, -0xa8(%rbp) 
    0x1000025f3 <+275>: jmp 0x100002600    ; <+288> at main.swift 
    0x1000025f5 <+277>: xorl %eax, %eax 
    0x1000025f7 <+279>: movl %eax, %ecx 
    0x1000025f9 <+281>: movq %rcx, -0xa8(%rbp) 
    0x100002600 <+288>: movq -0xa8(%rbp), %rax 
    0x100002607 <+295>: movq %rax, -0x50(%rbp) 
    0x10000260b <+299>: movq %rax, %rdi 
    0x10000260e <+302>: callq 0x100509080    ; swift_errorRelease 
    0x100002613 <+307>: movq -0x58(%rbp), %rax 
    0x100002617 <+311>: movq (%rax), %rdi 
    0x10000261a <+314>: callq 0x10051b20a    ; symbol stub for: objc_release 
    0x10000261f <+319>: movq -0x58(%rbp), %rax 
    0x100002623 <+323>: addq $0x8, %rax 
    0x100002627 <+327>: movq -0x58(%rbp), %rdi 
    0x10000262b <+331>: testb $0x1, 0x28(%rdi) 
    0x10000262f <+335>: movq %rax, -0xb0(%rbp) 
    0x100002636 <+342>: jne 0x100002647    ; <+359> at main.swift:18 
    0x100002638 <+344>: movq -0xb0(%rbp), %rax 
    0x10000263f <+351>: movq %rax, %rdi 
    0x100002642 <+354>: callq 0x100002960    ; __swift_destroy_boxed_opaque_existential_0 at main.swift 
    0x100002647 <+359>: movq -0x58(%rbp), %rax 
    0x10000264b <+363>: addq $0x30, %rax 
    0x10000264f <+367>: movq -0x58(%rbp), %rcx 
    0x100002653 <+371>: testb $0x1, 0x38(%rcx) 
    0x100002657 <+375>: movq %rax, -0xb8(%rbp) 
    0x10000265e <+382>: jne 0x10000266f    ; <+399> at main.swift:18 
    0x100002660 <+384>: movq -0xb8(%rbp), %rax 
    0x100002667 <+391>: movq (%rax), %rdi 
    0x10000266a <+394>: callq 0x100001b40    ; outlined copy of Swift._VariantDictionaryBuffer with unmangled suffix ".1" 
    0x10000266f <+399>: addq $0xb8, %rsp 
    0x100002676 <+406>: popq %r13 
    0x100002678 <+408>: popq %rbp 
    0x100002679 <+409>: retq 

ああ!この行は二度目に現れた:

0x10000256d <+141>: callq 0x10029cfe0    ; Swift.Optional._bridgeToObjectiveC() -> Swift.AnyObject 

ので、コンパイラはあなたがAnyObjectをキャストしていることを見たとき、それは「ああ、それはクラスだと思っていることであるようにそれが見えるもの、それはいくつかの目的であるかもしれません-Cのものは確かにブリッジしてください」と答えたのに対し、Anyと表示されている場合は、「Herp derp、これはMyErrorですか?いいえ、それは_SwiftValueです。 Swiftチームがas?キーワードをコンテキストに応じて2つの全く異なるものにすることにしたことをうれしく思いませんか?

+0

したがって、すべての非オブジェクト(Int、struct、enumなどの値型)はオブジェクトにラップされるため、 'Notification'経由で送信できますか?これは本当に悲しい黒の魔法です。修正していただきありがとうございますが、 'AnyObject'へのキャストを忘れる可能性があるので、私は' class'の代わりにそれを使用することをまだ躊躇しています。それはおそらくオプションのキャスト 'にする必要があります' ...として? AnyObject ...の代わりにAnyObject ... 'を使用します。 – shelll

+0

ああ、スウィフトに黒い魔法がどれくらいあるのかわからない。<-> Objective-Cブリッジ。 –

+0

私が*考えていることを解釈して編集*しています。 –

関連する問題