短的答案:
對於來自NSObject
派生的類,它具有同名作爲現有Objective-C的方法替換該方法的迅捷性 。
你的情況
因此,
var size: CGSize {
return self.size()
}
遞歸調用自己,直到程序與堆棧溢出 (當然,這就是這個網站是爲:)中止。
如果您爲該屬性選擇不同的名稱,例如
var theSize: CGSize {
return self.size()
}
然後一切都很好。
龍答:
SKTexture
是NSObject
一個子類。因此所有的Swift屬性都是 「與Objective-C兼容」。因此,編譯器會生成一個可以從Objective-C代碼調用的getter方法。 size
屬性的getter方法是-size
方法。所以你現在有兩個-size
方法: 原來的SKTexture
和第二個定義在你的Swift代碼。
如果你做同樣的在同一個項目中 定義,那麼你會得到一個連接器警告自己的Objective-C類:
實例方法「大小」類別從/用戶/ ... /main.o在/Users/.../MyClass.o
覆蓋從類 方法如果Objective-C類是在外部框架中定義的(如在你的情況) 接頭不會注意到衝突。
現在return self.size()
調用生成的Objective-C getter方法,該方法依次調用擴展方法 。這導致「無限」遞歸併最終導致堆棧溢出。
這是由棧回溯,你可以用LLDB bt
命令得到證實時,該程序已崩潰:
* thread #1: tid = 0x3d2ef, 0x000000010fb15e01 libobjc.A.dylib`objc::DenseMapBase, unsigned long, true, objc::DenseMapInfo > >, DisguisedPtr, unsigned long, objc::DenseMapInfo >, true>::FindAndConstruct(DisguisedPtr const&) + 21, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=2, address=0x7fff51b9cfe8)
frame #0: 0x000000010fb15e01 libobjc.A.dylib`objc::DenseMapBase, unsigned long, true, objc::DenseMapInfo > >, DisguisedPtr, unsigned long, objc::DenseMapInfo >, true>::FindAndConstruct(DisguisedPtr const&) + 21
frame #1: 0x000000010fb13e14 libobjc.A.dylib`objc_object::sidetable_retain() + 94
* frame #2: 0x000000010d8674d9 cdtest2`ext.cdtest2.ObjectiveC.SKTexture.size.getter : C.CGSize(self=0x00007fcceea020f0) + 25 at AppDelegate.swift:19
frame #3: 0x000000010d867542 cdtest2`@objc ext.cdtest2.ObjectiveC.SKTexture.size.getter : C.CGSize + 34 at AppDelegate.swift:0
frame #4: 0x000000010d8674ed cdtest2`ext.cdtest2.ObjectiveC.SKTexture.size.getter : C.CGSize(self=0x00007fcceea020f0) + 45 at AppDelegate.swift:19
frame #5: 0x000000010d867542 cdtest2`@objc ext.cdtest2.ObjectiveC.SKTexture.size.getter : C.CGSize + 34 at AppDelegate.swift:0
frame #6: 0x000000010d8674ed cdtest2`ext.cdtest2.ObjectiveC.SKTexture.size.getter : C.CGSize(self=0x00007fcceea020f0) + 45 at AppDelegate.swift:19
frame #7: 0x000000010d867542 cdtest2`@objc ext.cdtest2.ObjectiveC.SKTexture.size.getter : C.CGSize + 34 at AppDelegate.swift:0
frame #8: 0x000000010d8674ed cdtest2`ext.cdtest2.ObjectiveC.SKTexture.size.getter : C.CGSize(self=0x00007fcceea020f0) + 45 at AppDelegate.swift:19
...
frame #149556: 0x000000010d8674ed cdtest2`ext.cdtest2.ObjectiveC.SKTexture.size.getter : C.CGSize(self=0x00007fcceea020f0) + 45 at AppDelegate.swift:19
frame #149557: 0x000000010d867542 cdtest2`@objc ext.cdtest2.ObjectiveC.SKTexture.size.getter : C.CGSize + 34 at AppDelegate.swift:0
frame #149558: 0x000000010d8694e0 cdtest2`cdtest2.AppDelegate.application (application=0x00007fccee8005a0, launchOptions=None, self=0x00007fccebc06410)(ObjectiveC.UIApplication, didFinishLaunchingWithOptions : Swift.Optional>) -> Swift.Bool + 112 at AppDelegate.swift:83
frame #149559: 0x000000010d8697b0 cdtest2`@objc cdtest2.AppDelegate.application (cdtest2.AppDelegate)(ObjectiveC.UIApplication, didFinishLaunchingWithOptions : Swift.Optional>) -> Swift.Bool + 560 at AppDelegate.swift:0
...
frame #149572: 0x000000010d86bcaa cdtest2`main + 42 at AppDelegate.swift:0
frame #149573: 0x00000001102f0145 libdyld.dylib`start + 1
這(希望)解釋也就是爲什麼這兩個someTexture.size().width
和someTexture.size.width
出現問題: 在這兩種情況下,都會調用自定義擴展方法。
好的,非常感謝你!直到現在我還不知道這個LLDB欺騙者。我想這是我以前應該學會的東西...... – 2014-12-08 19:52:28