Návrh rozhraní Xamarin. iOS APIXamarin.iOS API Design

Kromě základních základních knihoven tříd, které jsou součástí mono, je Xamarin. iOS dodáván s vazbami pro různá rozhraní API pro iOS, které vývojářům umožňují vytvářet nativní aplikace pro iOS s mono.In addition to the core Base Class Libraries that are part of Mono, Xamarin.iOS ships with bindings for various iOS APIs to allow developers to create native iOS applications with Mono.

V jádru Xamarin. iOS je k dispozici modul spolupráce, který překládá C# World s cílem-C World a vazby pro rozhraní API pro iOS C, jako je CoreGraphics a OPENGL ES.At the core of Xamarin.iOS, there is an interop engine that bridges the C# world with the Objective-C world, and bindings for the iOS C-based APIs like CoreGraphics and OpenGL ES.

Běhový modul runtime ke komunikaci s cílovým kódem jazyka C je v MonoTouch. ObjCRuntime.The low-level runtime to communicate with Objective-C code is in MonoTouch.ObjCRuntime. Kromě toho jsou k dispozici vazby pro základní, CoreFoundation a UIKit .Additionally, bindings for Foundation, CoreFoundation, and UIKit are provided.

Principy návrhuDesign Principles

Tato část podrobně popisuje naše principy návrhu pro vazby Xamarin. iOS (vztahují se také na Xamarin. Mac, vazby mono pro cíl-C v macOS):This section details some of our design principles for the Xamarin.iOS bindings (they also apply to Xamarin.Mac, the Mono bindings for Objective-C on macOS):

  • Postupujte podle pokynů pro návrh rozhraní .Follow the Framework Design Guidelines

  • Umožněte vývojářům podtřídou účel-C třídy:Allow developers to subclass Objective-C classes:

    • Odvození od existující třídyDerive from an existing class
    • Volání základního konstruktoru pro řetězeníCall the base constructor to chain
    • Přepisování metod by se mělo provádět v systému přepsání jazyka C#Overriding methods should be done with C#'s override system
    • Podtřídy by měly fungovat s standardními konstruktory jazyka C#Subclassing should work with C# standard constructs
  • Nezveřejňujte vývojáře pro selektory v objektivu a v jazyce C.Do not expose developers to Objective-C selectors

  • Poskytnutí mechanismu pro volání libovolných účelových knihoven jazyka CProvide a mechanism to call arbitrary Objective-C libraries

  • Udělejte běžné cílení úloh v jazyce C snadné a tvrdé cílení úkolů v jazyce C.Make common Objective-C tasks easy and hard Objective-C tasks possible

  • Vystavení vlastností cíl-C jako vlastností jazyka C#Expose Objective-C properties as C# properties

  • Vystavení rozhraní API silného typu:Expose a strongly typed API:

    • Zvýšit bezpečnost typůIncrease type safety
    • Minimalizovat běhové chybyMinimize runtime errors
    • Získat IntelliSense IDE u návratových typůGet IDE IntelliSense on return types
    • Umožňuje místní dokumentaci pro IDE.Allows for IDE popup documentation
  • Podpora průzkumu rozhraní API v integrovaném vývojovém prostředí:Encourage in-IDE exploration of the APIs:

    • Například místo vystavení slabě typovaného pole takto:For example, instead of exposing a weakly typed array, like this:

      NSArray *getViews
      

      Zveřejňujte silný typ, například takto:Expose a strong type, like this:

      NSView [] Views { get; set; }
      

      Použití silných typů poskytuje Visual Studio pro Mac možnost automatického dokončování při procházení rozhraní API, zpřístupňuje všechny System.Array operace na vrácené hodnotě a umožňuje, aby se návratová hodnota účastnila LINQ.Using strong types gives Visual Studio for Mac the ability to do autocompletion while browsing the API, makes all of the System.Array operations available on the returned value, and allows the return value to participate in LINQ.

  • Nativní typy jazyka C#:Native C# types:

    • NSString stane stringNSString becomes string

    • intParametry a uint parametrů, které by měly být výčty v c# výčty a výčty c# s [Flags] atributyTurn int and uint parameters that should have been enums into C# enumerations and C# enumerations with [Flags] attributes

    • Namísto typů neutrálních NSArray objektů zveřejňujte pole jako pole silného typu.Instead of type-neutral NSArray objects, expose arrays as strongly typed arrays.

    • Pro události a oznámení Dejte uživatelům možnost volby mezi:For events and notifications, give users a choice between:

      • Verze silného typu ve výchozím nastaveníA strongly typed version by default
      • Slabě zadaná verze pro pokročilé případy použitíA weakly typed version for advanced use cases
  • Podpora vzoru delegáta cíl-C:Support the Objective-C delegate pattern:

    • Systém událostí v jazyce C#C# event system
    • Vystavení delegátů C# (výrazy lambda, anonymní metody a System.Delegate ) pro cílení rozhraní API v jazyce C jako blokyExpose C# delegates (lambdas, anonymous methods, and System.Delegate) to Objective-C APIs as blocks

SestaveníAssemblies

Xamarin. iOS obsahuje mnoho sestavení, která tvoří profil Xamarin. iOS.Xamarin.iOS includes many assemblies that constitute the Xamarin.iOS Profile. Stránka sestavení obsahuje další informace.The Assemblies page has more information.

Hlavní obory názvůMajor Namespaces

ObjCRuntimeObjCRuntime

Obor názvů ObjCRuntime umožňuje vývojářům přemostění světů mezi jazyky C# a cíl-C.The ObjCRuntime namespace allows developers to bridge the worlds between C# and Objective-C. Toto je nová vazba, navržená speciálně pro iOS, na základě zkušeností z kakaa # a GTK #.This is a new binding, designed specifically for the iOS, based on the experience from Cocoa# and Gtk#.

ZákladFoundation

Obor názvů Foundation poskytuje základní datové typy navržené pro spolupráci s cílem – c Foundation Framework, který je součástí iOS a je základem pro objektově orientované programování v cíli-C.The Foundation namespace provides the basic data types designed to interoperate with the Objective-C Foundation framework that is part of the iOS and it is the base for object-oriented programming in Objective-C.

Zrcadlení Xamarin. iOS v jazyce C# hierarchie tříd od cíle – C.Xamarin.iOS mirrors in C# the hierarchy of classes from Objective-C. Například základní třída cíl-C Nsobjectu je použitelná z C# prostřednictvím Foundation. nsobjectu.For example, the Objective-C base class NSObject is usable from C# via Foundation.NSObject.

I když základní obor názvů poskytuje vazby pro základní typy cíl-C Foundation, v několika případech jsme namapovali základní typy na typy .NET.Although Foundation namespace provides bindings for the underlying Objective-C Foundation types, in a few cases we have mapped the underlying types to .NET types. Například:For example:

  • Namísto použití NSString a NSArraymodul runtime zpřístupňuje je jako řetězecC# s a silně typované polev rámci rozhraní API.Instead of dealing with NSString and NSArray, the runtime exposes them as C# strings and strongly typed arrays throughout the API.

  • V tuto chvíli jsou dostupná různá rozhraní API pro vývojáře, která vývojářům umožňují svázat s rozhraními API v jazyce C jiných dodavatelů, jiná rozhraní API pro iOS nebo rozhraní API, která nejsou aktuálně vázaná na Xamarin. iOS.Various helper APIs are exposed here to allow developers to bind third-party Objective-C APIs, other iOS APIs, or APIs that are not currently bound by Xamarin.iOS.

Další informace o rozhraních API pro vytváření vazeb najdete v části generátor vazeb Xamarin. iOS .For more information on binding APIs, see the Xamarin.iOS Binding Generator section.

NsobjectuNSObject

Typ nsobjectu je základem pro všechny vazby cíl-C.The NSObject type is the foundation for all the Objective-C bindings. Typy Xamarin. iOS zrcadlí dvě třídy typů z rozhraní API CocoaTouch pro iOS: typy C (obvykle se označují jako CoreFoundation typy) a typy cíl-C (které jsou odvozeny od třídy Nsobjectu).Xamarin.iOS types mirror two classes of types from the iOS CocoaTouch APIs: the C types (typically referred to as CoreFoundation types) and the Objective-C types (which all derive from the NSObject class).

Pro každý typ, který zrcadlí nespravovaný typ, lze získat nativní objekt prostřednictvím vlastnosti Handle .For each type that mirrors an unmanaged type, it is possible to obtain the native object through the Handle property.

I když mono bude poskytovat uvolňování paměti pro všechny vaše objekty, Foundation.NSObject implementuje rozhraní System. IDisposable .While Mono will provide garbage collection for all of your objects, the Foundation.NSObject implements the System.IDisposable interface. Můžete explicitně uvolnit prostředky všech daných Nsobjectu, aniž byste museli čekat, než systém uvolňování paměti vyplní.You can explicitly release the resources of any given NSObject without having to wait for the Garbage Collector to kick in. Explicitní uvolnění prostředků je důležité, pokud používáte těžké NSObjects, například UIImages, které mohou obsahovat ukazatele na velké bloky dat.Explicitly releasing resources is important when you are using heavy NSObjects, for example, UIImages that might hold pointers to large blocks of data.

Pokud váš typ potřebuje provést deterministické dokončení, přepište metodu nsobjectu. Dispose (bool) , kterou má parametr Dispose "bool disposing", a pokud je nastaveno na hodnotu true, znamená to, že je volána metoda Dispose, protože uživatel explicitně volal metodu Dispose () objektu.If your type needs to perform deterministic finalization, override the NSObject.Dispose(bool) method The parameter to Dispose is "bool disposing", and if set to true it means that your Dispose method is being called because the user explicitly called Dispose () on the object. Hodnota false znamená, že metoda Dispose (bool disposing) je volána z finalizační metody ve vlákně finalizační metody.A false value means that your Dispose(bool disposing) method is being called from the finalizer on the finalizer thread.

KategorieCategories

Od Xamarin. iOS 8,10 je možné vytvořit objektivní kategorie C z C#.Starting with Xamarin.iOS 8.10 it is possible to create Objective-C categories from C#.

K tomu je potřeba použít Category atribut, který určuje typ, který se rozšiřuje jako argument atributu.This is done using the Category attribute, specifying the type to extend as an argument to the attribute. Následující příklad způsobí, že instance rozšiřuje NSString.The following example will for instance extend NSString.

[Category (typeof (NSString))]

Každá metoda kategorie používá normální mechanismus pro export metod do cíle – C pomocí Export atributu:Each category method is using the normal mechanism for exporting methods to Objective-C using the Export attribute:

[Export ("today")]
public static string Today ()
{
    return "Today";
}

Všechny spravované metody rozšíření musí být statické, ale je možné vytvořit cílové metody instance jazyka C pomocí standardní syntaxe pro rozšiřující metody v jazyce C#:All managed extension methods must be static, but it’s possible to create Objective-C instance methods using the standard syntax for extension methods in C#:

[Export ("toUpper")]
public static string ToUpper (this NSString self)
{
    return self.ToString ().ToUpper ();
}

a první argument metody rozšíření bude instancí, na které byla metoda vyvolána.and the first argument to the extension method will be the instance on which the method was invoked.

Kompletní příklad:Complete example:

[Category (typeof (NSString))]
public static class MyStringCategory
{
    [Export ("toUpper")]
    static string ToUpper (this NSString self)
    {
        return self.ToString ().ToUpper ();
    }
}

Tento příklad přidá nativní metodu instance toUpper do třídy NSString, která může být vyvolána z cíle-C.This example will add a native toUpper instance method to the NSString class, which can be invoked from Objective-C.

[Category (typeof (UIViewController))]
public static class MyViewControllerCategory
{
    [Export ("shouldAutoRotate")]
    static bool GlobalRotate ()
    {
        return true;
    }
}

Jedním z situací, kdy je to užitečné, je přidání metody do celé sady tříd v základu kódu, například tím, že by všechny UIViewController instance nahlásily, že mohou provést otočení:One scenario where this is useful is adding a method to an entire set of classes in your codebase, for example, this would make all UIViewController instances report that they can rotate:

[Category (typeof (UINavigationController))]
class Rotation_IOS6 {
      [Export ("shouldAutorotate:")]
      static bool ShouldAutoRotate (this UINavigationController self)
      {
          return true;
      }
}
PreserveAttributePreserveAttribute

PreserveAttribute je vlastní atribut, který se používá k oznámení mtouch – Nástroj pro nasazení Xamarin. iOS – pro zachování typu nebo člena typu, během fáze při zpracování aplikace za účelem snížení velikosti.PreserveAttribute is a custom attribute that is used to tell mtouch – the Xamarin.iOS deployment tool – to preserve a type, or a member of a type, during the phase when the application is processed to reduce its size.

Každý člen, který není staticky propojen aplikací, podléhá odebrání.Every member that is not statically linked by the application is subject to be removed. Proto tento atribut slouží k označení členů, kteří nejsou staticky odkazováni, ale jsou stále vyžadovány vaší aplikací.Hence, this attribute is used to mark members that are not statically referenced, but that are still needed by your application.

Pokud například vytváříte instanci typů dynamicky, můžete chtít zachovat výchozí konstruktor vašich typů.For instance, if you instantiate types dynamically, you may want to preserve the default constructor of your types. Pokud používáte serializaci XML, je vhodné zachovat vlastnosti vašich typů.If you use XML serialization, you may want to preserve the properties of your types.

Tento atribut lze použít pro každého člena typu nebo pro samotný typ.You can apply this attribute on every member of a type, or on the type itself. Pokud chcete zachovat celý typ, můžete použít syntaxi [Preserve (AllMembers = true)] pro typ.If you want to preserve the whole type, you can use the syntax [Preserve (AllMembers = true)] on the type.

UIKitUIKit

Obor názvů UIKit obsahuje mapování 1:1 na všechny součásti uživatelského rozhraní, které tvoří CocoaTouch ve formě tříd jazyka C#.The UIKit namespace contains a one-to-one mapping to all of the UI components that make up CocoaTouch in the form of C# classes. Rozhraní API bylo upraveno tak, aby následovalo podle konvencí používaných v jazyce C#.The API has been modified to follow the conventions used in the C# language.

Delegáty jazyka C# jsou k dispozici pro běžné operace.C# delegates are provided for common operations. Další informace najdete v části Delegáti .For more information, see the delegates section.

Aplikace OpenGLESOpenGLES

Pro OpenGL distribuujeme upravenou verzi rozhraní API OpenTK a objektově orientované vazby na OpenGL, která byla upravena tak, aby používala datové typy a struktury CoreGraphics, a zpřístupňuje pouze funkce, které jsou k dispozici v iOS.For OpenGLES, we distribute a modified version of the OpenTK API, an object-oriented binding to OpenGL that has been modified to use CoreGraphics data types and structures, and only exposing the functionality that is available on iOS.

Funkce OpenGLs 1,1 je k dispozici prostřednictvím typu ES11.GL.OpenGLES 1.1 functionality is available through the ES11.GL type.

Funkce OpenGLs 2,0 je k dispozici prostřednictvím typu ES20.GL.OpenGLES 2.0 functionality is available through the ES20.GL type.

Funkce OpenGLs 3,0 je k dispozici prostřednictvím typu ES30.GL.OpenGLES 3.0 functionality is available through the ES30.GL type.

Návrh vazbyBinding Design

Xamarin. iOS není pouze vazba na základní cílovou platformu C.Xamarin.iOS is not merely a binding to the underlying Objective-C platform. Rozšiřuje systém typů .NET a odesílá systém pro lepší blendy v jazycích C# a cíl-C.It extends the .NET type system and dispatches system to better blend C# and Objective-C.

Stejně jako volání nespravovaného kódu je užitečný nástroj k vyvolání nativních knihoven v systému Windows a Linux, nebo jako podpora IJW lze použít pro zprostředkovatele komunikace s objekty COM v systému Windows, Xamarin. iOS rozšiřuje modul runtime tak, aby podporoval objekty C# pro objekty objektivní-C.Just as P/Invoke is a useful tool to invoke native libraries on Windows and Linux, or as IJW support can be used for COM interop on Windows, Xamarin.iOS extends the runtime to support binding C# objects to Objective-C objects.

Diskuze v následujících částech není potřeba pro uživatele, kteří vytvářejí aplikace Xamarin. iOS, ale pomůže vývojářům pochopit, jak se všechno dokončí, a pomůže jim při vytváření složitějších aplikací.The discussion in the next few sections is not necessary for users that are creating Xamarin.iOS applications, but will help developers understand how things are done and will assist them when creating more complicated applications.

TypyTypes

Tam, kde to vedlo smysl, jsou typy C# namísto základních typů v jazyce C# k dispozici.Where it made sense, C# types are exposed instead of low-level Foundation types, to the C# universe. To znamená, že rozhraní API používá typ "String" v jazyce c# namísto NSString a používá pole c# silně typované místo vystavení NSArray.This means that the API uses the C# "string" type instead of NSString and it uses strongly typed C# arrays instead of exposing NSArray.

Obecně platí, že v návrhu Xamarin. iOS a Xamarin. Mac se podkladový NSArray objekt nezveřejňuje.In general, in the Xamarin.iOS and Xamarin.Mac design, the underlying NSArray object is not exposed. Namísto toho modul runtime automaticky převede NSArray na pole silného typu některé NSObject třídy.Instead, the runtime automatically converts NSArrays to strongly typed arrays of some NSObject class. Proto Xamarin. iOS nezveřejňuje slabě zadaná metoda, jako je GetViews, aby vracela NSArray:So, Xamarin.iOS does not expose a weakly typed method like GetViews to return an NSArray:

NSArray GetViews ();

Místo toho vazba zpřístupňuje návratovou hodnotu silného typu, například:Instead, the binding exposes a strongly typed return value, like this:

UIView [] GetViews ();

V nástroji je k dispozici několik metod NSArray , v případě rohovéch případů, kde můžete chtít použít NSArray přímo, ale jejich použití se ve vazbě rozhraní API nedoporučuje.There are a few of methods exposed in NSArray, for the corner cases where you might want to use an NSArray directly, but their use is discouraged in the API binding.

Navíc v Classic API místo vystavení CGRect , CGPoint a CGSize z rozhraní API pro CoreGraphics nahrazujeme je System.Drawing implementacemi RectangleF , PointF a SizeF tak, jak by pomohli vývojářům zachovat existující kód OpenGL, který používá OpenTK.Additionally, in the Classic API instead of exposing CGRect, CGPoint, and CGSize from the CoreGraphics API, we replaced them with the System.Drawing implementations RectangleF, PointF, and SizeF as they would help developers preserve existing OpenGL code that uses OpenTK. Při použití nového 64 Unified API by se měla použít rozhraní API CoreGraphics.When using the new 64-bit Unified API, the CoreGraphics API should be used.

DědičnostInheritance

Návrh rozhraní API Xamarin. iOS umožňuje vývojářům rozšiřování nativních typů cíle jazyka C stejným způsobem, jako by rozšířily typ jazyka C#, pomocí klíčového slova override v odvozené třídě a zřetězení až k základní implementaci pomocí klíčového slova Base jazyka C#.The Xamarin.iOS API design allows developers to extend native Objective-C types in the same way that they would extend a C# type, using the "override" keyword on a derived class, and chaining up to the base implementation using the "base" C# keyword.

Tento návrh umožňuje vývojářům vyhnout se v práci s výběrovými sestavami jazyka C jako součást jejich procesu vývoje, protože celý systém cílů-C je již zabalen uvnitř knihoven Xamarin. iOS.This design allows developers to avoid dealing with Objective-C selectors as part of their development process, because the entire Objective-C system is already wrapped inside the Xamarin.iOS libraries.

Typy a Interface BuilderTypes and Interface Builder

Při vytváření tříd .NET, které jsou instancemi typů vytvořených pomocí Interface Builder, je nutné poskytnout konstruktor, který přijímá jeden IntPtr parametr.When you create .NET classes that are instances of types created by Interface Builder, you need to provide a constructor that takes a single IntPtr parameter. To je nutné pro svázání instance spravovaného objektu s nespravovaným objektem.This is required to bind the managed object instance with the unmanaged object. Kód se skládá z jednoho řádku, například takto:The code consists of a single line, like this:

public partial class void MyView : UIView {
   // This is the constructor that you need to add.
   public MyView (IntPtr handle) : base (handle) {}
}

DelegátiDelegates

Objektivní – C a C# mají různé významy pro slovo delegáta v jednotlivých jazycích.Objective-C and C# have different meanings for the word delegate in each language.

V cíli-C World a v dokumentaci, kterou najdete online o CocoaTouch, je delegát obvykle instancí třídy, která bude reagovat na sadu metod.In the Objective-C world, and in the documentation that you will find online about CocoaTouch, a delegate is typically an instance of a class that will respond to a set of methods. To je podobné rozhraní C# s rozdílem, že metody nejsou vždy povinné.This is similar to a C# interface, with the difference being that the methods are not always mandatory.

Tito Delegáti hrají důležitou roli v UIKit a dalších CocoaTouch rozhraních API.These delegates play an important role in UIKit and other CocoaTouch APIs. Slouží k provádění různých úloh:They are used to accomplish various tasks:

  • Pro poskytování oznámení vašemu kódu (podobně jako doručování událostí v jazyce C# nebo GTK +).To provide notifications to your code (Similar to event delivery in C# or Gtk+).
  • Pro implementaci modelů pro ovládací prvky vizualizace dat.To implement models for data visualization controls.
  • Chcete-li řídit chování ovládacího prvku.To drive the behavior of a control.

Programovací model byl navržen pro minimalizaci vytváření odvozených tříd pro změnu chování ovládacího prvku.The programming pattern was designed to minimize the creation of derived classes to alter behavior for a control. Toto řešení je podobné jako v duchu toho, jaké další sady nástrojů grafického uživatelského rozhraní se v průběhu let prováděly: signály GTK, sloty QT, události WinForms, události WPF/Silverlight atd.This solution is similar in spirit to what other GUI toolkits have done over the years: Gtk's signals, Qt slots, Winforms events, WPF/Silverlight events and so on. Chcete-li se vyhnout používání stovek rozhraní (jeden pro každou akci) nebo vyžadovat, aby vývojáři implementovali příliš mnoho metod, které nepotřebují, cíl-C podporuje definice volitelných metod.To avoid having hundreds of interfaces (one for each action) or requiring developers to implement too many methods they do not need, Objective-C supports optional method definitions. To se liší od rozhraní C#, která vyžadují implementaci všech metod.This is different than C# interfaces that require all methods to be implemented.

V třídách cíl-C uvidíte, že třídy, které používají tento programovací model, zpřístupňují vlastnost, delegate která je požadována k implementaci povinné části rozhraní a nula nebo více volitelných částí.In Objective-C classes, you will see that classes that use this programming pattern expose a property, called delegate, which is required to implement the mandatory parts of the interface and zero, or more, of the optional parts.

V Xamarin. iOS jsou k dispozici tři vzájemně exkluzivní mechanismy vytváření vazeb na tyto delegáty:In Xamarin.iOS three mutually exclusive mechanisms to bind to these delegates are offered:

  1. Prostřednictvím událostí.Via events.
  2. Silného typu přes Delegate vlastnostStrongly typed via a Delegate property
  3. Volně typované přes WeakDelegate vlastnostLoosely typed via a WeakDelegate property

Zvažte například třídu UIWebView.For example, consider the UIWebView class. Tím se odešle do instance UIWebViewDelegate, která je přiřazena k vlastnosti Delegate.This dispatches to a UIWebViewDelegate instance, which is assigned to the delegate property.

Prostřednictvím událostíVia Events

Pro mnoho typů vytvoří Xamarin. iOS automaticky odpovídající delegáta, který přesměruje UIWebViewDelegate volání na události jazyka C#.For many types, Xamarin.iOS will automatically create an appropriate delegate, which will forward the UIWebViewDelegate calls onto C# events. Pro UIWebView:For UIWebView:

Tento jednoduchý program například zaznamenává čas zahájení a ukončení při načítání webového zobrazení:For example, this simple program records the start and end times when loading a web view:

DateTime startTime, endTime;
var web = new UIWebView (new CGRect (0, 0, 200, 200));
web.LoadStarted += (o, e) => startTime = DateTime.Now;
web.LoadFinished += (o, e) => endTime = DateTime.Now;
Prostřednictvím vlastnostíVia Properties

Události jsou užitečné v případě, že událost může být více než jeden odběratel.Events are useful when there might be more than one subscriber to the event. Události jsou také omezeny na případy, kdy neexistuje žádná návratová hodnota z kódu.Also, events are limited to cases where there is no return value from the code.

V případech, kdy se očekává, že kód vrátí hodnotu, jsme místo vlastností zvolili vlastnost.For cases where the code is expected to return a value, we opted instead for properties. To znamená, že v daném okamžiku v objektu lze nastavit pouze jednu metodu.This means that only one method can be set at a given time in an object.

Tento mechanismus můžete například použít k zavření klávesnice na obrazovce obslužné rutiny pro UITextField :For example, you can use this mechanism to dismiss the keyboard on the screen on the handler for a UITextField:

void SetupTextField (UITextField tf)
{
    tf.ShouldReturn = delegate (textfield) {
        textfield.ResignFirstResponder ();
        return true;
    }
}

UITextFieldVlastnost 's ShouldReturn v tomto případě přebírá jako argument delegáta, který vrací logickou hodnotu, a určuje, zda má funkce TextField dělat něco s tlačítkem pro vrácení, které je stisknuto.The UITextField's ShouldReturn property in this case takes as an argument a delegate that returns a bool value and determines whether the TextField should do something with the Return button being pressed. V naší metodě vrátíme volajícímu hodnotu true , ale také z obrazovky odebereme klávesnici (k tomu dojde, když volání TextField ResignFirstResponder ).In our method, we return true to the caller, but we also remove the keyboard from the screen (this happens when the textfield calls ResignFirstResponder).

Silného typu prostřednictvím vlastnosti DelegateStrongly Typed via a Delegate Property

Pokud nechcete používat události, můžete poskytnout vlastní podtřídou UIWebViewDelegate a přiřadit ji k vlastnosti UIWebView. Delegate .If you would prefer not to use events, you can provide your own UIWebViewDelegate subclass and assign it to the UIWebView.Delegate property. Po přiřazení UIWebView. Delegate již mechanismus odeslání události UIWebView nebude fungovat a metody UIWebViewDelegate budou vyvolány, když dojde k odpovídajícím událostem.Once UIWebView.Delegate has been assigned, the UIWebView event dispatch mechanism will no longer function, and the UIWebViewDelegate methods will be invoked when the corresponding events occur.

Tento jednoduchý typ například zaznamenává čas potřebný k načtení webového zobrazení:For example, this simple type records the time it takes to load a web view:

class Notifier : UIWebViewDelegate  {
    DateTime startTime, endTime;

    public override LoadStarted (UIWebView webview)
    {
        startTime = DateTime.Now;
    }

    public override LoadingFinished (UIWebView webView)
    {
        endTime= DateTime.Now;
    }
}

Výše uvedený kód se používá v následujícím kódu:The above is used in code like this:

var web = new UIWebView (new CGRect (0, 0, 200, 200));
web.Delegate = new Notifier ();

Výše uvedené vytvoří UIWebViewer a pošle mu pokyn, aby odesílal zprávy do instance oznamovatele, což je třída, kterou jsme vytvořili pro reakci na zprávy.The above will create a UIWebViewer and it will instruct it to send messages to an instance of Notifier, a class that we created to respond to messages.

Tento model se používá také k řízení chování pro určité ovládací prvky, například v případě UIWebView, vlastnost UIWebView. ShouldStartLoad umožňuje UIWebView instanci určovat, zda UIWebView bude načtena stránka nebo ne.This pattern is also used to control behavior for certain controls, for example in the UIWebView case, the UIWebView.ShouldStartLoad property allows the UIWebView instance to control whether the UIWebView will load a page or not.

Tento vzor slouží také k poskytování dat na vyžádání pro několik ovládacích prvků.The pattern is also used to provide the data on demand for a few controls. Například ovládací prvek UITableView je výkonný ovládací prvek pro vykreslování tabulky – a vzhled i obsah jsou řízeny instancí třídy UITableViewDataSourceFor example, the UITableView control is a powerful table-rendering control – and both the look and the contents are driven by an instance of a UITableViewDataSource

Volně typované přes vlastnost WeakDelegateLoosely Typed via the WeakDelegate Property

Kromě vlastnosti silného typu má také delegát slabý typ, který umožňuje vývojářům navazovat vazby odlišně v případě potřeby.In addition to the strongly typed property, there is also a weak typed delegate that allows the developer to bind things differently if desired. Všude Delegate , kde je ve vazbě Xamarin. iOS k dispozici vlastnost silného typu, WeakDelegate je k dispozici také odpovídající vlastnost.Everywhere a strongly typed Delegate property is exposed in Xamarin.iOS's binding, a corresponding WeakDelegate property is also exposed.

Při použití WeakDelegate , zodpovídáte za správné upravení vaší třídy pomocí atributu Export pro určení selektoru.When using the WeakDelegate, you are responsible for properly decorating your class using the Export attribute to specify the selector. Například:For example:

class Notifier : NSObject  {
    DateTime startTime, endTime;

    [Export ("webViewDidStartLoad:")]
    public void LoadStarted (UIWebView webview)
    {
        startTime = DateTime.Now;
    }

    [Export ("webViewDidFinishLoad:")]
    public void LoadingFinished (UIWebView webView)
    {
        endTime= DateTime.Now;
    }
}

[...]

var web = new UIWebView (new CGRect (0, 0, 200, 200));
web.WeakDelegate = new Notifier ();

Po WeakDelegate přiřazení vlastnosti se Delegate vlastnost nepoužije.Once the WeakDelegate property has been assigned, the Delegate property will not be used. Kromě toho, Pokud implementujete metodu v zděděné základní třídě, kterou chcete [exportovat], je nutné vytvořit veřejnou metodu.Additionally, if you implement the method in an inherited base class that you wish to [Export], you must make it a public method.

Mapování vzoru cíl-C delegáta na C#Mapping of the Objective-C delegate pattern to C#

Když vidíte ukázky typu cíl-C, které vypadají takto:When you see Objective-C samples that look like this:

foo.delegate = [[SomethingDelegate] alloc] init]

Tato možnost dává jazyku pro vytvoření a vytvoření instance třídy "SomethingDelegate" a přiřadí hodnotu vlastnosti Delegate v proměnné foo.This instructs the language to create and construct an instance of the class "SomethingDelegate" and assign the value to the delegate property on the foo variable. Tento mechanismus podporuje Xamarin. iOS a C# syntaxe:This mechanism is supported by Xamarin.iOS and C# the syntax is:

foo.Delegate = new SomethingDelegate ();

V Xamarin. iOS jsme poskytovali silně typové třídy, které se mapují na třídy delegáta cíl-C.In Xamarin.iOS, we have provided strongly typed classes that map to the Objective-C delegate classes. Chcete-li je použít, budete moci roztřídit a přepsat metody definované implementací Xamarin. iOS.To use them, you will be subclassing and overriding the methods defined by Xamarin.iOS's implementation. Další informace o tom, jak fungují, najdete v části modely níže.For more information on how they work, see the section "Models" below.

Mapování delegátů na C#Mapping Delegates to C#

UIKit obecně používá delegáty cíl-C ve dvou formách.UIKit in general uses Objective-C delegates in two forms.

První formulář poskytuje rozhraní pro model komponenty.The first form provides an interface to a component's model. Například jako mechanismus pro poskytování dat na vyžádání pro zobrazení, jako je například zařízení pro ukládání dat pro zobrazení seznamu.For example, as a mechanism to provide data on demand for a view, such as the data storage facility for a List view. V těchto případech byste měli vždy vytvořit instanci správné třídy a přiřadit proměnnou.In these cases, you should always create an instance of the proper class and assign the variable.

V následujícím příkladu poskytujeme UIPickerView implementaci pro model, který používá řetězce:In the following example, we provide the UIPickerView with an implementation for a model that uses strings:

public class SampleTitleModel : UIPickerViewTitleModel {

    public override string TitleForRow (UIPickerView picker, nint row, nint component)
    {
        return String.Format ("At {0} {1}", row, component);
    }
}

[...]

pickerView.Model = new MyPickerModel ();

Druhým formulářem je poskytnutí oznámení pro události.The second form is to provide notification for events. V takových případech, i když stále zveřejňujeme rozhraní API ve formě popsané výše, poskytujeme také události v jazyce C#, které by měly být jednodušší pro použití pro rychlé operace a integrované s anonymními delegáty a lambda výrazy v jazyce C#.In those cases, although we still expose the API in the form outlined above, we also provide C# events, which should be simpler to use for quick operations and integrated with anonymous delegates and lambda expressions in C#.

Můžete se například přihlásit k odběru UIAccelerometer událostí:For example, you can subscribe to UIAccelerometer events:

UIAccelerometer.SharedAccelerometer.Acceleration += (sender, args) => {
   UIAcceleration acc = args.Acceleration;
   Console.WriteLine ("Time={0} at {1},{2},{3}", acc.Time, acc.X, acc.Y, acc.Z);
}

Tyto dvě možnosti jsou k dispozici tam, kde dávají smysl, ale jako programátor musíte vybrat jednu nebo druhou.The two options are available where they make sense, but as a programmer you must pick one or the other. Pokud vytvoříte vlastní instanci respondéru nebo delegáta se silným typem a přiřadíte ji, události jazyka C# nebudou funkční.If you create your own instance of a strongly typed responder/delegate and assign it, the C# events will not be functional. Použijete-li události jazyka C#, metody ve třídě respondér/Delegate nebudou nikdy volány.If you use the C# events, the methods in your responder/delegate class will never be called.

Předchozí příklad, který se používá, UIWebView lze zapsat pomocí výrazů jazyka C# 3,0 lambda, například takto:The previous example that used UIWebView can be written using C# 3.0 lambdas like this:

var web = new UIWebView (new CGRect (0, 0, 200, 200));
web.LoadStarted += () => { startTime = DateTime.Now; }
web.LoadFinished += () => { endTime = DateTime.Now; }

Reakce na událostiResponding to Events

V případě kódu v cíli C jsou někdy obslužné rutiny událostí pro více ovládacích prvků a poskytovatelů informací pro více ovládacích prvků hostovány ve stejné třídě.In Objective-C code, sometimes event handlers for multiple controls and providers of information for multiple controls, will be hosted in the same class. To je možné, protože třídy reagují na zprávy a pokud třídy reagují na zprávy, je možné propojit objekty dohromady.This is possible because classes respond to messages, and as long as classes respond to messages, it is possible to link objects together.

Jak už bylo popsáno, Xamarin. iOS podporuje programovací model založený na událostech jazyka C# a vzor delegáta cíl-C, kde můžete vytvořit novou třídu, která implementuje delegáta a přepíše požadované metody.As previously detailed, Xamarin.iOS supports both the C# event-based programming model, and the Objective-C delegate pattern, where you can create a new class that implements the delegate and overrides the desired methods.

Je také možné podporovat vzor objektivu a jazyka C, kde jsou všechny reakce na více různých operací hostovány ve stejné instanci třídy.It is also possible to support Objective-C's pattern where responders for multiple different operations are all hosted in the same instance of a class. V takovém případě budete muset použít funkce na nízké úrovni vazby Xamarin. iOS.To do this though, you will have to use low-level features of the Xamarin.iOS binding.

Například pokud jste chtěli, aby vaše třída reagovala na UITextFieldDelegate.textFieldShouldClear : zpráva i UIWebViewDelegate.webViewDidStartLoad : ve stejné instanci třídy, je nutné použít deklaraci atributu [Export]:For example, if you wanted your class to respond to both the UITextFieldDelegate.textFieldShouldClear: message and the UIWebViewDelegate.webViewDidStartLoad: in the same instance of a class, you would have to use the [Export] attribute declaration:

public class MyCallbacks : NSObject {
    [Export ("textFieldShouldClear:"]
    public bool should_we_clear (UITextField tf)
    {
        return true;
    }

    [Export ("webViewDidStartLoad:")]
    public void OnWebViewStart (UIWebView view)
    {
        Console.WriteLine ("Loading started");
    }
}

Názvy jazyka C# pro tyto metody nejsou důležité. všechny tyto záležitosti jsou řetězce předané atributu [Export].The C# names for the methods are not important; all that matters are the strings passed to the [Export] attribute.

Při použití tohoto stylu programování zajistěte, aby parametry jazyka C# odpovídaly skutečným typům, které bude modul runtime předávat.When using this style of programming, ensure that the C# parameters match the actual types that the runtime engine will pass.

ModelyModels

V zařízeních úložiště UIKit nebo v reagujících, které jsou implementovány pomocí pomocných tříd, jsou tyto odkazy odkazovány v kódu cíl-C jako Delegáti a jsou implementovány jako protokoly.In UIKit storage facilities, or in responders that are implemented using helper classes, these are referenced in the Objective-C code as delegates, and they are implemented as protocols.

Cílové protokoly C jsou jako rozhraní, ale podporují volitelné metody – to znamená, že není nutné implementovat všechny metody, aby mohl protokol fungovat.Objective-C protocols are like interfaces, but they support optional methods – that is, not all of the methods need to be implemented for the protocol to work.

Existují dva způsoby implementace modelu.There are two ways of implementing a model. Můžete ji buď implementovat ručně, nebo použít existující definice silného typu.You can either implement it manually or use the existing strongly typed definitions.

Ruční mechanismus je nutný, když se pokusíte implementovat třídu, která není vázaná na Xamarin. iOS.The manual mechanism is necessary when you try to implement a class that has not been bound by Xamarin.iOS. Je snadné:It is easy to do:

  • Označení třídy pro registraci pomocí modulu runtimeFlag your class for registration with the runtime
  • Pro každou metodu, kterou chcete přepsat, použijte atribut [Export] se skutečným názvem selektoru.Apply the [Export] attribute with the actual selector name on each method you want to override
  • Vytvořte instanci třídy a předejte ji.Instantiate the class, and pass it.

Například následující implementuje jenom jednu z volitelných metod v definici protokolu UIApplicationDelegate:For example, the following implement only one of the optional methods in the UIApplicationDelegate protocol definition:

public class MyAppController : NSObject {
        [Export ("applicationDidFinishLaunching:")]
        public void FinishedLaunching (UIApplication app)
        {
                SetupWindow ();
        }
}

Název selektoru cíle C ("applicationDidFinishLaunching:") je deklarován s atributem export a třída je zaregistrována s [Register] atributem.The Objective-C selector name ("applicationDidFinishLaunching:") is declared with the Export attribute and the class is registered with the [Register] attribute.

Xamarin. iOS poskytuje deklarace silného typu, které jsou připravené k použití, které nevyžadují ruční vazby.Xamarin.iOS provides strongly typed declarations, ready to use, that do not require manual binding. Pro podporu tohoto programovacího modelu podporuje modul runtime Xamarin. iOS atribut [model] v deklaraci třídy.To support this programming model, the Xamarin.iOS runtime supports the [Model] attribute on a class declaration. To informuje modul runtime, že by neměl nastavovat všechny metody ve třídě, pokud metody nejsou explicitně implementovány.This informs the runtime that it should not wire up all the methods in the class, unless the methods are explicitly implemented.

To znamená, že v UIKit třídy, které představují protokol s nepovinnými metodami, jsou zapsány takto:This means that in UIKit, the classes that represent a protocol with optional methods are written like this:

[Model]
public class SomeViewModel : NSObject {
    [Export ("someMethod:")]
    public virtual int SomeMethod (TheView view) {
       throw new ModelNotImplementedException ();
    }
    ...
}

Pokud chcete implementovat model, který implementuje pouze některé metody, je nutné provést pouze přepsání metod, které vás zajímají, a Ignorovat jiné metody.When you want to implement a model that only implements some of the methods, all you have to do is to override the methods that you are interested in, and ignore the other methods. Modul runtime bude zapojovat pouze přepsané metody, nikoli původní metody pro cíl-C World.The runtime will only hook up the overwritten methods, not the original methods to the Objective-C world.

Ekvivalent k předchozí manuální ukázce je:The equivalent to the previous manual sample is:

public class AppController : UIApplicationDelegate {
    public override void FinishedLaunching (UIApplication uia)
    {
     ...
    }
}

Výhodou je, že nemusíte dig do souborů hlaviček cíl-C k vyhledání selektoru, typů argumentů nebo mapování na C# a k získání IntelliSense z Visual Studio pro Mac, společně se silnými typyThe advantages are that there is no need to dig into the Objective-C header files to find the selector, the types of the arguments, or the mapping to C#, and that you get intellisense from Visual Studio for Mac, along with strong types

XIB a C#XIB Outlets and C#

Toto je popis nízké úrovně, jak umožňují integraci s jazykem C# a jsou k dispozici pro pokročilé uživatele Xamarin. iOS.This is a low-level description of how Outlets integrate with C# and is provided for advanced users of Xamarin.iOS. Při použití Visual Studio pro Mac se mapování provádí automaticky na pozadí za použití vygenerovaného kódu na letu.When using Visual Studio for Mac, the mapping is done automatically behind the scenes using generated code on the flight for you.

Při návrhu uživatelského rozhraní pomocí Interface Builder budete navrhovat pouze vzhled aplikace a navázali jste některá výchozí připojení.When you design your user interface with Interface Builder, you will only be designing the look of the application and will establish some default connections. Chcete-li programově načíst informace, změnit chování ovládacího prvku za běhu nebo upravit ovládací prvek za běhu, je nutné vytvořit vazby některých ovládacích prvků ke spravovanému kódu.If you want to programmatically fetch information, alter the behavior of a control at runtime or modify the control at runtime, it is necessary to bind some of the controls to your managed code.

K tomu je potřeba provést několik kroků:This is done in a few steps:

  1. Přidejte do vlastníka souboru deklaraci zásuvky .Add the outlet declaration to your File's owner.
  2. Připojte svůj ovládací prvek k vlastníkovi souboru.Connect your control to the File's owner.
  3. Uložte uživatelské rozhraní a připojení do souboru XIB/NIB.Store the UI plus the connections into your XIB/NIB file.
  4. Načtěte soubor NIB za běhu.Load the NIB file at runtime.
  5. Přístup k proměnné zásuvkyAccess the outlet variable.

Postup (1) až (3) je popsaný v dokumentaci společnosti Apple pro vytváření rozhraní s Interface Builder.The steps (1) through (3) are covered in Apple's documentation for building interfaces with Interface Builder.

Při použití Xamarin. iOS bude vaše aplikace muset vytvořit třídu, která je odvozená z UIViewController.When using Xamarin.iOS, your application will need to create a class that derives from UIViewController. Je implementována takto:It is implemented it like this:

public class MyViewController : UIViewController {
    public MyViewController (string nibName, NSBundle bundle) : base (nibName, bundle)
    {
        // You can have as many arguments as you want, but you need to call
        // the base constructor with the provided nibName and bundle.
    }
}

Pak můžete načíst své soubor viewcontroller ze souboru NIB:Then to load your ViewController from a NIB file, you do this:

var controller = new MyViewController ("HelloWorld", NSBundle.MainBundle, this);

Tím načtete uživatelské rozhraní z NIB.This loads the user interface from the NIB. Pro přístup k výstupům teď je potřeba informovat modul runtime, ke kterému chceme přistupovat.Now, to access the outlets, it is necessary to inform the runtime that we want to access them. K tomu UIViewController musí podtřída deklarovat vlastnosti a opatřit je poznámkami pomocí atributu [Connect].To do this, the UIViewController subclass needs to declare the properties and annotate them with the [Connect] attribute. Nějak tak:Like this:

[Connect]
UITextField UserName {
    get {
        return (UITextField) GetNativeField ("UserName");
    }
    set {
        SetNativeField ("UserName", value);
    }
}

Implementace vlastnosti je ta, která ve skutečnosti načte a ukládá hodnotu pro skutečný nativní typ.The property implementation is the one that actually fetches and stores the value for the actual native type.

K tomu se nemusíte starat při použití Visual Studio pro Mac a InterfaceBuilder.You do not need to worry about this when using Visual Studio for Mac and InterfaceBuilder. Visual Studio pro Mac automaticky zrcadlí všechna deklarovaná odbytiště s kódem v částečné třídě, která je kompilována jako součást projektu.Visual Studio for Mac automatically mirrors all the declared outlets with code in a partial class that is compiled as part of your project.

VoličeSelectors

Základní koncept programování typu cíl-C je selektorů.A core concept of Objective-C programming is selectors. Často budete mít rozhraní API, které vyžaduje, abyste předávali selektor, nebo očekáváte, že váš kód reaguje na selektor.You will often come across APIs that require you to pass a selector, or expects your code to respond to a selector.

Vytváření nových selektorů v jazyce C# je snadné – stačí vytvořit novou instanci ObjCRuntime.Selector třídy a použít výsledek na jakémkoli místě v rozhraní API, které to vyžaduje.Creating new selectors in C# is easy – you just create a new instance of the ObjCRuntime.Selector class and use the result in any place in the API that requires it. Například:For example:

var selector_add = new Selector ("add:plus:");

Pro metodu jazyka C#, která reaguje na volání selektoru, musí dědit od NSObject typu a metoda jazyka c# musí být upravena pomocí názvu selektor pomocí [Export] atributu.For a C# method respond to a selector call, it must inherit from the NSObject type and the C# method must be decorated with the selector name using the [Export] attribute. Například:For example:

public class MyMath : NSObject {
    [Export ("add:plus:")]
    int Add (int first, int second)
    {
         return first + second;
    }
}

Názvy selektoru se musí přesně shodovat, včetně všech vnitřních a koncových dvojtečk (":"), pokud jsou k dispozici.Selector names must match exactly, including all intermediate and trailing colons (":"), if present.

Nsobjectu konstruktoryNSObject Constructors

Většina tříd v Xamarin. iOS, která je odvozena z, NSObject bude vystavovat konstruktory specifické pro funkcionalitu objektu, ale budou také zveřejňovat různé konstruktory, které nejsou okamžitě zřejmé.Most classes in Xamarin.iOS that derive from NSObject will expose constructors specific to the functionality of the object, but they will also expose various constructors that are not immediately obvious.

Konstruktory jsou používány následujícím způsobem:The constructors are used as follows:

public Foo (IntPtr handle)

Tento konstruktor slouží k vytvoření instance třídy, pokud modul runtime potřebuje mapovat vaši třídu na nespravovanou třídu.This constructor is used to instantiate your class when the runtime needs to map your class to an unmanaged class. K tomu dojde, když nahrajete soubor XIB/NIB.This happens when you load a XIB/NIB file. V tomto okamžiku modul runtime cíl-C vytvoří objekt v nespravovaném světě a tento konstruktor se zavolá k inicializaci spravované strany.At this point, the Objective-C runtime will have created an object in the unmanaged world, and this constructor will be called to initialize the managed side.

Obvykle stačí provést volání základního konstruktoru s parametrem popisovače a v těle, který je nezbytný k inicializaci.Typically, all you need to do is call the base constructor with the handle parameter, and in the body, do any initialization that is necessary.

public Foo ()

Toto je výchozí konstruktor pro třídu a v Xamarin. iOS, který poskytuje třídy, inicializuje třídu Foundation. Nsobjectu a všechny třídy v between a na konci zřetězí tuto metodu do metody cíl-C init třídy.This is the default constructor for a class, and in Xamarin.iOS provided classes, this initializes the Foundation.NSObject class and all of the classes in between, and at the end, chains this to the Objective-C init method on the class.

public Foo (NSObjectFlag x)

Tento konstruktor slouží k inicializaci instance, ale zabraňuje kódu v volání metody "init" na konci.This constructor is used to initialize the instance, but prevent the code from calling the Objective-C "init" method at the end. Toto se obvykle používá, pokud již máte zaregistrováno pro inicializaci (při použití [Export] v konstruktoru) nebo pokud jste již svou inicializaci dokončili jiným významem.You typically use this when you already have registered for initialization (when you use [Export] on your constructor) or when you have already done your initialization through another mean.

public Foo (NSCoder coder)

Tento konstruktor je k dispozici pro případy, kdy je objekt inicializován z instance NSCoding.This constructor is provided for the cases where the object is being initialized from an NSCoding instance.

VýjimkyExceptions

Návrh rozhraní Xamarin. iOS API nevyvolává jako výjimky jazyka C# výjimky v cíli-C.The Xamarin.iOS API design does not raise Objective-C exceptions as C# exceptions. Návrh vynutil, že se na první místo neodesílají žádné uvolňování paměti v prvním místě a že všechny výjimky, které musí být vyprodukovány, jsou vyráběny samotným před tím, než jsou data v cíli C-světě předána neplatným datům.The design enforces that no garbage be sent to the Objective-C world in the first place and that any exceptions that must be produced are produced by the binding itself before invalid data is ever passed to the Objective-C world.

OznámeníNotifications

V systémech iOS a OS X se vývojáři můžou přihlásit k odběru oznámení, která jsou všesměrově vysílaná základní platformou.In both iOS and OS X, developers can subscribe to notifications that are broadcast by the underlying platform. To se provádí pomocí NSNotificationCenter.DefaultCenter.AddObserver metody.This is done by using the NSNotificationCenter.DefaultCenter.AddObserver method. AddObserverMetoda přijímá dva parametry. jedna je oznámení, ke kterému se chcete přihlásit. druhá je metoda, která má být vyvolána při vyvolání oznámení.The AddObserver method takes two parameters; one is the notification that you want to subscribe to; the other is the method to be invoked when the notification is raised.

V Xamarin. iOS a Xamarin. Mac jsou klíče pro různá oznámení hostovány ve třídě, která spouští oznámení.In both Xamarin.iOS and Xamarin.Mac, the keys for the various notifications are hosted on the class that triggers the notifications. Například oznámení vyvolaná v UIMenuController jsou hostována jako static NSString vlastnosti ve UIMenuController třídách, které končí názvem "Notification".For example, the notifications raised by the UIMenuController are hosted as static NSString properties in the UIMenuController classes that end with the name "Notification".

Správa pamětiMemory Management

Xamarin. iOS má systém uvolňování paměti, který postará o uvolnění prostředků, když se už nepoužívají.Xamarin.iOS has a garbage collector that will take care of releasing resources for you when they are no longer in use. Kromě uvolňování paměti všechny objekty, které jsou odvozeny z NSObject implementace System.IDisposable rozhraní.In addition to the garbage collector, all objects that derive from NSObject implement the System.IDisposable interface.

Nsobjectu a IDisposableNSObject and IDisposable

Vystavení IDisposable rozhraní je pohodlný způsob, jak pomáhat vývojářům při uvolňování objektů, které by mohly zapouzdřit velké bloky paměti (například UIImage může vypadat jenom jako ukazatel Innocent, ale může to ukazovat na 2 MB obrázku) a další důležité a omezené prostředky (jako je například vyrovnávací paměť pro dekódování videa).Exposing the IDisposable interface is a convenient way of assisting developers in releasing objects that might encapsulate large blocks of memory (for example, a UIImage might look like just an innocent pointer, but could be pointing to a 2 megabyte image) and other important and finite resources (like a video decoding buffer).

Nsobjectu implementuje rozhraní IDisposable a také vzor Dispose .NET.NSObject implements the IDisposable interface and also the .NET Dispose pattern. To umožňuje vývojářům, kteří Nsobjectu podtřídou, přepsat chování při uvolnění a uvolnit své vlastní prostředky na vyžádání.This allows developers that subclass NSObject to override the Dispose behavior and release their own resources on demand. Zvažte například tento kontroler zobrazení, který uchovává spoustu imagí:For example, consider this view controller that keeps around a bunch of images:

class MenuViewController : UIViewController {
    UIImage breakfast, lunch, dinner;
    [...]
    public override void Dispose (bool disposing)
    {
        if (disposing){
             if (breakfast != null) breakfast.Dispose (); breakfast = null;
             if (lunch != null) lunch.Dispose (); lunch = null;
             if (dinner != null) dinner.Dispose (); dinner = null;
        }
        base.Dispose (disposing)
    }
}

Pokud je vyřazen spravovaný objekt, již není užitečný.When a managed object is disposed, it is no longer useful. Je možné, že stále máte odkaz na objekty, ale objekt je pro všechny záměry a účely v tomto okamžiku neplatný.You might still have a reference to the objects, but the object is for all intents and purposes invalid at this point. Některá rozhraní API rozhraní .NET tuto chybu zajišťují vyvoláním ObjectDisposedException, pokud se pokusíte o přístup k jakýmkoli metodám u uvolněného objektu, například:Some .NET APIs ensure this by throwing an ObjectDisposedException if you try to access any methods on a disposed object, for example:

var image = UIImage.FromFile ("demo.png");
image.Dispose ();
image.XXX = false;  // this at this point is an invalid operation

I když stále máte přístup k proměnné "image", je ve skutečnosti neplatný odkaz a již neukazuje na objekt cíl-C, který image drží.Even if you can still access the variable "image", it is really an invalid reference and no longer points to the Objective-C object that held the image.

Ale zrušení objektu v jazyce C# neznamená, že objekt bude nutně zničen.But disposing an object in C# does not mean that the object will necessarily be destroyed. Vše, co uděláte, je uvolnění odkazu, který měl objekt jazyka C#.All you do is release the reference that C# had to the object. Je možné, že prostředí kakaa by mohlo vést k vlastnímu odkazování na jejich použití.It is possible that the Cocoa environment might have kept a reference around for its own use. Pokud jste například nastavili vlastnost image UIImageView na obrázek a pak jste image odstranili, podkladová UIImageView převzala svůj vlastní odkaz a zachová odkaz na tento objekt, dokud ho nedokončíte.For example, if you set a UIImageView's Image property to an image, and then you dispose the image, the underlying UIImageView had taken its own reference and will keep a reference to this object until it is finished using it.

Kdy volat DisposeWhen to call Dispose

Vyvolejte metodu Dispose, pokud potřebujete mono, abyste mohli zbavit svůj objekt.Call Dispose when you need Mono to get rid of your object. Možný případ použití je v případě, že mono nemá žádné znalosti o tom, že vaše Nsobjectu ve skutečnosti drží odkaz na důležitý prostředek, jako je například paměť nebo fond informací.A possible use case is when Mono has no knowledge that your NSObject is actually holding a reference to an important resource like memory, or an information pool. V takových případech byste měli zavolat metodu Dispose, aby hned uvolnila odkaz na paměť, a ne čekat, až mono provede cyklus uvolňování paměti.In those cases, you should call Dispose to immediately release the reference to the memory, instead of waiting for Mono to perform a garbage collection cycle.

Interně, když mono vytvoří odkazy NSString z řetězců jazyka C#, okamžitě je odstraní, aby snížila množství práce, které musí systém uvolňování paměti provést.Internally, when Mono creates NSString references from C# strings, it will dispose them immediately to reduce the amount of work that the garbage collector has to do. Čím méně objektů, které se mají řešit, tím rychleji se spustí GC.The fewer objects around to deal with, the faster the GC will run.

Kdy zachovat odkazy na objektyWhen to Keep References to Objects

Jedna z vedlejších účinků, kterou Automatická správa paměti má za následek, že GC vyřadí nepoužívané objekty, pokud na ně neexistují žádné odkazy.One side-effect that automatic memory management has is that the GC will get rid of unused objects as long as there are no references to them. Což může někdy mít překvapivé vedlejší účinky, například pokud vytvoříte místní proměnnou, která bude obsahovat kontroler zobrazení nejvyšší úrovně, nebo okno nejvyšší úrovně a pak zmizí vaše pozadí.Which sometimes can have surprising side effects, for example, if you create a local variable to hold your top-level view controller, or your top-level window, and then having those vanish behind your back.

Pokud nezachováte odkaz ve statických proměnných nebo proměnných instancí na vaše objekty, mono Happily volá metodu Dispose () na těchto objektech a vydá odkaz na objekt.If you do not keep a reference in your static or instance variables to your objects, Mono will happily call the Dispose() method on them, and they will release the reference to the object. Vzhledem k tomu, že to může být jediný neřízený odkaz, modul runtime cíl-C zničí objekt za vás.Since this might be the only outstanding reference, the Objective-C runtime will destroy the object for you.