========@objc=============
@objc 使用介紹 在swift3中,編譯器自動推斷@objc,換句話說,它自動添加@objc
在swift4中,編譯器不再自動推斷,你必須顯式添加@objc
在swift 中 如果一個按鈕添加點擊方法 如果定義為Private 或者 定義為 FilePrivate 那麼會在Addtaget方法中找不到私人方法
但是又不想把方法暴露出來,避免外界訪問 ,那麼可以在私人方法前加 @objc 修飾 那麼它就能找到那個方法了
@objc 作用
1 fileprivate 或者 private 保證方法私人 能在同一個類 或者 同一個檔案(extension)中訪問這個方法 如果定義為private 那麼只能在一個類中訪問 不能在類擴充中訪問
2 允許這個函數在“運行時”通過oc的訊息機制調用 ============== extension=======================
擴充聲明使用關鍵字 extension:
extension SomeType {
// 加到SomeType的新功能寫到這裡
}
一個擴充可以擴充一個已有類型,使其能夠適配一個或多個協議,文法格式如下:
extension SomeType:SomeProtocol,AnotherProctocol {
// 協議實現寫到這裡
}
========================================is和as 類型轉換
Swift 語言類型轉換可以判斷執行個體的類型。也可以用於檢測執行個體類型是否屬於其父類或者子類的執行個體。
Swift 中類型轉換使用 is 和 as 操作符實現,is 用於檢測值的類型,as 用於轉換類型。
類型轉換也可以用來檢查一個類是否實現了某個協議。
向下轉型,用類型轉換操作符(as? 或 as!)
當你不確定向下轉型可以成功時,用類型轉換的條件形式(as?)。條件形式的類型轉換總是返回一個可選值(optional value),並且若下轉是不可能的,可選值將是 nil。
只有你可以確定向下轉型一定會成功時,才使用強制形式(as!)。當你試圖向下轉型為一個不正確的類型時,強制形式的類型轉換會觸發一個執行階段錯誤。
var chemCount = 0
var mathsCount = 0
for item in sa {
// 類型轉換的條件形式
if let show = itemas?Chemistry {
print("化學主題是: '\(show.physics)',\(show.equations)")
// 強制形式
} else iflet example = itemas? Maths {
print("數學主題是: '\(example.physics)', \(example.formulae)")
}
}
類型轉換用於檢測執行個體類型是否屬於特定的執行個體類型。
你可以將它用在類和子類的階層上,檢查特定類執行個體的類型並且轉換這個類執行個體的類型成為這個階層中的其他類型。
類型檢查使用 is 關鍵字。
操作符 is 來檢查一個執行個體是否屬於特定子類型。若執行個體屬於那個子類型,類型檢查操作符返回 true,否則返回 false。
var chemCount = 0
var mathsCount = 0
for item in sa {
// 如果是一個 Chemistry 類型的執行個體,返回 true,相反返回 false。
if item isChemistry {
++chemCount
} else if itemisMaths {
++mathsCount
}
}
Swift為不確定類型提供了兩種特殊類型別名: AnyObject可以代表任何class類型的執行個體。 Any可以表示任何類型,包括方法類型(function types)。 ========================存取控制修飾符===========================
協議也可以被限定在一定的範圍內使用,包括協議裡的全域常量、變數和函數。
存取控制基於模組與源檔案。
模組指的是以獨立單元構建和發布的 Framework 或 Application。在 Swift 中的一個模組可以使用 import 關鍵字引入另外一個模組。
源檔案是單個源碼檔案,它通常屬於一個模組, 源檔案可以包含多個類和函數 的定義。
Swift 為代碼中的實體提供了四種不同的存取層級:public、internal、fileprivate、private。
存取層級 |
定義 |
public |
可以訪問自己模組中源檔案裡的任何實體,別人也可以通過引入該模組來訪問源檔案裡的所有實體。 |
internal |
可以訪問自己模組中源檔案裡的任何實體,但是別人不能訪問該模組中源檔案裡的實體。 |
fileprivate |
檔案內私人,只能在當前源檔案中使用。 |
private |
只能在類中訪問,離開了這個類或者結構體的範圍外面就無法訪問。 |
public 為最進階存取層級,private 為最低級存取層級。 除非有特殊的說明,否則實體都使用預設的存取層級 internal。
*************函數類型存取權限
函數的存取層級需要根據該函數的參數類型和傳回型別的存取層級得出。
下面的例子定義了一個名為someFunction全域函數,並且沒有明確地申明其存取層級。
func someFunction() -> (SomeInternalClass,SomePrivateClass) {
// 函數實現
}
函數中其中一個類 SomeInternalClass 的存取層級是 internal,另一個 SomePrivateClass 的存取層級是 private。所以根據元組存取層級的原則,該元組的存取層級是 private(元組的存取層級與元組中存取層級最低的類型一致)。
因為該函數傳回型別的存取層級是 private,所以你必須使用 private 修飾符,明確的聲明該函數:
private func someFunction() -> (SomeInternalClass,SomePrivateClass) {
// 函數實現
}
將該函數申明為 public 或 internal,或者使用預設的存取層級 internal 都是錯誤的,因為如果這樣你就無法訪問 private 層級的傳回值。
*****************枚舉類型存取權限
枚舉中成員的存取層級繼承自該枚舉,你不能為枚舉中的成員單獨申明不同的存取層級。
比如,枚舉 Student 被明確的申明為 public 層級,那麼它的成員 Name,Mark 的存取層級同樣也是 public:
執行個體
public enum Student {
case Name(String)
case Mark(Int,Int,Int)
}
var studDetails = Student.Name("Swift")
var studMarks = Student.Mark(98,97,95)
switch studMarks {
case .Name(let studName):
print("學生名: \(studName).")
case .Mark(let Mark1,let Mark2,let Mark3):
print("學產生績: \(Mark1),\(Mark2),\(Mark3)")
}
子類的存取層級不得高於父類的存取層級。比如說,父類的存取層級是internal,子類的存取層級就不能申明為public。
常量、變數、屬性不能擁有比它們的類型更高的存取層級。
比如說,你定義一個public層級的屬性,但是它的類型是private層級的,這是編譯器所不允許的。
同樣,下標也不能擁有比索引類型或傳回型別更高的存取層級。
如果常量、變數、屬性、下標索引的定義類型是private層級的,那麼它們必須要明確的申明存取層級為private:
常量、變數、屬性、下標索引的Getters和Setters的存取層級繼承自它們所屬成員的存取層級。
Setter的存取層級可以低於對應的Getter的存取層級,這樣就可以控制變數、屬性或下標索引的讀寫權限。
==================可選項========