第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號(hào)安全,請(qǐng)及時(shí)綁定郵箱和手機(jī)立即綁定
已解決430363個(gè)問題,去搜搜看,總會(huì)有你想問的

覆蓋Swift擴(kuò)展中的方法

覆蓋Swift擴(kuò)展中的方法

慕神8447489 2019-08-12 10:19:44
覆蓋Swift擴(kuò)展中的方法我傾向于只將必需品(存儲(chǔ)屬性,初始化器)放入我的類定義中,并將其他所有內(nèi)容移動(dòng)到自己的extension類中,有點(diǎn)像extension我將與之合并的每個(gè)邏輯塊// MARK:。例如,對(duì)于UIView子類,我最終會(huì)得到與布局相關(guān)的東西的擴(kuò)展,一個(gè)用于訂閱和處理事件等等。在這些擴(kuò)展中,我不可避免地必須覆蓋一些UIKit方法,例如layoutSubviews。我從未注意到這種方法有任何問題 - 直到今天。以此類層次結(jié)構(gòu)為例:public class C: NSObject {     public func method() { print("C") }}public class B: C {}extension B {     override public func method() { print("B") }}public class A: B {}extension A {     override public func method() { print("A") }}(A() as A).method()(A() as B).method()(A() as C).method()輸出是A B C。這對(duì)我來說沒什么意義。我讀到有關(guān)靜態(tài)分派的協(xié)議擴(kuò)展,但這不是協(xié)議。這是一個(gè)常規(guī)類,我希望在運(yùn)行時(shí)動(dòng)態(tài)調(diào)度方法調(diào)用。顯然,呼叫C至少應(yīng)該動(dòng)態(tài)調(diào)度和產(chǎn)生C?如果我刪除繼承NSObject并創(chuàng)建C一個(gè)根類,編譯器會(huì)抱怨說declarations in extensions cannot override yet,我已經(jīng)讀過了。但是NSObject,如果根類改變了什么呢?將兩個(gè)覆蓋移動(dòng)到它們的類聲明中會(huì)產(chǎn)生A A A預(yù)期的效果,僅移動(dòng)B產(chǎn)生A B B,僅移動(dòng)A產(chǎn)生C B C,最后一個(gè)產(chǎn)生對(duì)我來說完全沒有意義:即使是靜態(tài)輸入的A產(chǎn)生也不再產(chǎn)生A-output!將dynamic關(guān)鍵字添加到定義或覆蓋確實(shí)似乎給了我“從類層次結(jié)構(gòu)中向下的所需行為”...讓我們把我們的例子改成一些不太構(gòu)造的東西,實(shí)際上是什么讓我發(fā)布了這個(gè)問題:public class B: UIView {}extension B {     override public func layoutSubviews() { print("B") }}public class A: B {}extension A {     override public func layoutSubviews() { print("A") }}(A() as A).layoutSubviews()(A() as B).layoutSubviews()(A() as UIView).layoutSubviews()我們現(xiàn)在得到A B A。在這里,我不能以任何方式使UIView的layoutSubviews動(dòng)態(tài)化。將兩個(gè)覆蓋移動(dòng)到他們的類聲明中A A A再次獲得我們,只有A或者只有B仍然可以獲得我們A B A。dynamic再次解決了我的問題。理論上我可以添加dynamic到override我做過的所有事情,但我覺得我在這里做了別的錯(cuò)事。使用extensions像我一樣分組代碼是不是真的錯(cuò)了?
查看完整描述

3 回答

?
慕標(biāo)5832272

TA貢獻(xiàn)1966條經(jīng)驗(yàn) 獲得超4個(gè)贊

Swift的目標(biāo)之一是靜態(tài)調(diào)度,或者更確切地說是動(dòng)態(tài)調(diào)度的減少。然而,Obj-C是一種非常動(dòng)態(tài)的語言。您所看到的情況來自于兩種語言之間的聯(lián)系以及它們協(xié)同工作的方式。它不應(yīng)該真正編譯。

關(guān)于擴(kuò)展的一個(gè)要點(diǎn)是它們用于擴(kuò)展,而不是用于替換/覆蓋。從名稱和文檔中可以清楚地看出這是意圖。實(shí)際上,如果從代碼中取出Obj-C的鏈接(NSObject作為超類刪除),它將無法編譯。

因此,編譯器正在嘗試確定它可以靜態(tài)調(diào)度的內(nèi)容以及動(dòng)態(tài)分派的內(nèi)容,并且由于代碼中的Obj-C鏈接,它正在陷入差距。dynamic“工作” 的原因是因?yàn)樗仁筄bj-C連接所有東西,所以它總是動(dòng)態(tài)的。

因此,使用擴(kuò)展進(jìn)行分組并沒有錯(cuò),這很好,但是在擴(kuò)展中覆蓋它是錯(cuò)誤的。任何覆蓋都應(yīng)該在主類本身中,并調(diào)用擴(kuò)展點(diǎn)。


查看完整回答
反對(duì) 回復(fù) 2019-08-12
?
叮當(dāng)貓咪

TA貢獻(xiàn)1776條經(jīng)驗(yàn) 獲得超12個(gè)贊

有一種方法可以實(shí)現(xiàn)類簽名和實(shí)現(xiàn)(在擴(kuò)展中)的清晰分離,同時(shí)保持在子類中具有覆蓋的能力。訣竅是使用變量代替函數(shù)

如果確保在單獨(dú)的swift源文件中定義每個(gè)子類,則可以使用計(jì)算變量進(jìn)行覆蓋,同時(shí)保持相應(yīng)的實(shí)現(xiàn)在擴(kuò)展中干凈地組織。這將繞過Swift的“規(guī)則”,并使您的課程的API /簽名整齊地組織在一個(gè)地方:

 // ---------- BaseClass.swift -------------
 public class BaseClass
 {
     public var method1:(Int) -> String { return doMethod1 }

     public init() {}
 }

 // the extension could also be in a separate file  
 extension BaseClass
 {    
     private func doMethod1(param:Int) -> String { return "BaseClass \(param)" }
 }

...

 // ---------- ClassA.swift ----------
 public class A:BaseClass
 {
    override public var method1:(Int) -> String { return doMethod1 }
 }

 // this extension can be in a separate file but not in the same // file as the BaseClass extension that defines its doMethod1 implementation extension A {
    private func doMethod1(param:Int) -> String 
    { 
       return "A \(param) added to \(super.method1(param))" 
    }
 }

...

 // ---------- ClassB.swift ---------- public class B:A {
    override public var method1:(Int) -> String { return doMethod1 }
 }

 extension B {
    private func doMethod1(param:Int) -> String 
    { 
       return "B \(param) added to \(super.method1(param))" 
    }
 }

每個(gè)類的擴(kuò)展都能夠?yàn)閷?shí)現(xiàn)使用相同的方法名稱,因?yàn)樗鼈兪撬接械牟⑶冶舜瞬豢梢姡ㄖ灰鼈冊(cè)趩为?dú)的文件中)。

正如您所看到的,繼承(使用變量名稱)可以使用super.variablename正常工作

 BaseClass().method1(123)         --> "BaseClass 123"
 A().method1(123)                 --> "A 123 added to BaseClass 123"
 B().method1(123)                 --> "B 123 added to A 123 added to BaseClass 123"
 (B() as A).method1(123)          --> "B 123 added to A 123 added to BaseClass 123"
 (B() as BaseClass).method1(123)  --> "B 123 added to A 123 added to BaseClass 123"


查看完整回答
反對(duì) 回復(fù) 2019-08-12
  • 3 回答
  • 0 關(guān)注
  • 756 瀏覽

添加回答

舉報(bào)

0/150
提交
取消
微信客服

購(gòu)課補(bǔ)貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動(dòng)學(xué)習(xí)伙伴

公眾號(hào)

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號(hào)