Xamarin.iOS 可讓您跨平台分享以 C# 撰寫的平台獨立程式碼。 不過,現有的 iOS 應用程式可能想要利用 Objective-C 已建立的程式代碼。 本文可作為想要移至 Xamarin 和 C# 語言的開發人員的簡短入門 Objective-C 。
在 Objective-C 不需要平臺特定程序代碼的地方利用 C#,讓這類程式代碼可用於非 Apple 裝置,藉此從 Xamarin 開發 iOS 和 macOS 應用程式獲益。 例如 Web 服務、JSON 與 XML 剖析,以及自訂演算法等接著可以用於跨平台行為。
為了在維護現有 Objective-C 資產的同時利用 Xamarin,前者可以在 Xamarin 稱為系結的技術中向 C# 公開,而該系結可讓程式代碼浮 Objective-C 出水面到 Managed、C# 世界。 此外,您也可以視需要將程式碼逐行移植為 C#。 不過,無論此方法是系結還是移植,都必須具備和 C# 的 Objective-C 一些知識,才能有效地利用 Xamarin.iOS 的現有 Objective-C 程式代碼。
Objective-C Interop
目前不支援使用可從呼叫的 Xamarin.iOS Objective-C在 C# 中建立連結庫的機制。 主要原因是除了繫結之外,也需要 Mono 執行階段。 不過,您仍然可以在 中 Objective-C建立大部分邏輯,包括使用者介面。 若要這樣做,請將程式代碼包裝在連結 Objective-C 庫中,並建立與其系結。 需要 Xamarin.iOS 才能啟動應用程式 (表示它必須建立 Main
進入點)。 之後,任何其他邏輯都可以在 中 Objective-C,透過系結向 C# 公開(或透過 P/Invoke)。 如此一來,您可以在 C# 中 Objective-C 保留平臺特定邏輯,並開發與平台無關的部分。
本文強調一些主要相似之處,並對比了這兩種語言的數個差異,以在使用 Xamarin.iOS 移至 C# 時做為入門,無論是系結至現有的 Objective-C 程式代碼,還是將它移植到 C#。
如需建立系結的詳細資訊,請參閱系結 Objective-C中的其他檔。
語言比較
Objective-C 和 C# 在語法和運行時間觀點上都是非常不同的語言。 Objective-C 是動態語言,並使用訊息傳遞配置,而 C# 則是靜態類型。 語法明智, Objective-C 就像Smalltalk,而 C# 則從Java衍生了大部分基本語法,不過近年來已成熟,以包含許多Java以外的功能。
也就是說,和 C# 都有數個語言功能 Objective-C 在函式上相似。 從 C# 或移植Objective-C到 C# 時建立程式Objective-C代碼的系結時,瞭解這些相似之處很有用。
通訊協定與介面
Objective-C和 C# 都是單一繼承語言。 不過,這兩種語言都支援在給定類別中實作多個介面。 在這些 Objective-C 邏輯介面中稱為 通訊協定 ,而在 C# 中則稱為 介面。 實作方面,C# 介面和 Objective-C 通訊協議之間的主要差異是後者可以有選擇性的方法。 如需詳細資訊,請參閱事件、委派與通訊協定一文。
類別與擴充方法
Objective-C 允許將方法新增至類別,您可能沒有使用 Categories 的實作程式代碼。 在 C# 中,可以透過「擴充方法」了解相同的概念。
擴充方法可讓您將靜態方法新增至 類別,其中 C# 中的靜態方法類似於 中的 Objective-C類別方法。 例如,下列程式代碼會將名為 ScrollToBottom
的方法新增至 UITextView
類別,而這個方法又是系結至 UIKit 類別的 Objective-CUITextView
Managed 類別:
public static class UITextViewExtensions
{
public static void ScrollToBottom (this UITextView textView)
{
// code to scroll textView
}
}
然後,當 UITextView
的執行個體在程式碼中建立時,您將可以在自動完成清單中看到該方法,如下所示:
當擴充方法被呼叫時,該執行個體會被傳遞到引數,例如此範例中的 textView
。
架構與元件
Objective-C 封裝特殊目錄中稱為架構的相關類別。 不過在 C# 與 .NET 中,組件是用來提供可重複使用的預先編譯程式碼。 在 iOS 外部的環境中,組件包含中繼語言程式碼 (IL),這在執行階段會透過 Just-In-Time (JIT) 來編譯。 不過,Apple 不允許在 App Store 上發行的 iOS 應用程式中執行 JIT 編譯的程式代碼。 因此,使用 Xamarin 開發且以 iOS 為目標的 C# 程式碼是預先編譯 (AOT),這會產生單一 Unix 可執行檔,以及包含在應用程式套件組合中的中繼資料檔案。
選取器與具名參數
Objective-C 方法本質上會以其本質在選取器中包含參數名稱。 例如,AddCrayon:WithColor:
之類的選取器在程式碼中使用時會清楚傳達每個參數的意義。 C# 也選擇性支援具名引數。
例如,C# 中使用具名引數的類似程式碼看起來會像這樣:
AddCrayon (crayon: myCrayon, color: UIColor.Blue);
雖然 C# 在 4.0 版語言中新增此支援,實務上並不常使用。 不過,若要在您的程式碼中明確表示,確實支援它。
標頭與命名空間
做為 C 的超集, Objective-C 會針對與實作檔案分開的公用宣告使用標頭。 C# 不使用標頭檔案。 不同於 Objective-C,C# 程式代碼包含在命名空間中。 若要將可用程式碼包含在某些命名空間中,您會新增 using 指示詞到實作檔案頂端,或用完整命名空間限定類型。
例如,下列程式碼包含 UIKit
命名空間,進而將該命名空間中的每個類別提供給實作:
using UIKit;
namespace MyAppNamespace
{
// implementation of classes
}
此外,上物程式碼中的命名空間關鍵字會設定用於實作檔案本身的命名空間。 若多個實作檔案共用相同的命名空間,則您不需要一併將命名空間包含在 directive 指示詞中,因為那就有這樣的意涵。
屬性
Objective-C和 C# 都有屬性的概念,可提供存取子方法的高階抽象概念。 在 Objective-C 編譯程式指示詞中 @property ,用來有效地產生存取子方法。 相反地,C# 包含對語言本身內屬性的支援。 C# 屬性可使用會存取支援欄位的較長樣式來實作,或使用較短的自動屬性語法來實作,如下列範例所示:
// automatic property syntax
public string Name { get; set; }
// property implemented with a backing field
string address;
public string Address {
get {
// could add additional code here
return address;
}
set {
address = value;
}
}
Static 關鍵字
static 關鍵詞在 和 C# 之間Objective-C具有非常不同的意義。 在 Objective-C 靜態函式中,用來將函式的範圍限制為目前的檔案。 不過在 C# 中,範圍是透過 public、private 與 internal 關鍵字來維持。
當 static 關鍵詞套用至 中的 Objective-C變數時,變數會在函數調用之間維護其值。
C# 也有 Satic 關鍵字。 套用至方法時,它會有效地執行 修飾詞在 中Objective-C執行的相同動作+
。 也就是說,它會建立類別方法。 同樣地,當被套用到其他建構 (例如欄位、屬性與事件) 時,它會讓那些成為它們被定義所在之類型的一部分,而不是具有該類型的任何執行個體。 您也可以設定為靜態類別,讓在該類別中的所有方法也必須是靜態的。
NSArray 與列表初始化
Objective-C 現在包含用於的 NSArray
常值語法,可讓您更輕鬆地初始化。 不過 C# 擁有稱為 List
(它是「泛型」) 的更豐富類型,這表示清單所持有的類型可透過建立清單的程式碼來提供 (就像 C++ 中的範本)。 此外,清單也支援自動初始化語法,如下所示:
MyClass object1 = new MyClass ();
MyClass object2 = new MyClass ();
List<MyClass> myList = new List<MyClass>{ object1, object2 };
區塊與 Lambda 運算式
Objective-C 會使用 區塊 來建立關閉,您可以在其中建立函式內嵌,以利用其封入狀態。 C# 具有類似的概念,它會使用 Lambda 運算式。 在 C# 中,Lambda 運算式是使用 =>
運算子所建立,如下所示:
(args) => {
// implementation code
};
如需有關 Lambda 運算式的詳細資訊,請參閱 Microsoft 的 C# 程式設計手冊.
摘要
在本文中,與 C# 之間 Objective-C 有各種不同的語言功能對比。 在某些案例中,我們說明了兩種語言中的類似功能,例如區塊與 Lambda 運算式,以及延伸方法的類別。 此外,我們也說明了兩種語言的相異之處,例如 C# 中的命名空間與 Static 關鍵字的意義。