型のバインド リファレンス ガイド

このドキュメントでは、API コントラクト ファイルに注釈を付けてバインディングと生成されたコードを駆動するために使用できる属性の一覧について説明します

Xamarin.iOS および Xamarin.Mac API コントラクトは、主に C# で、コードを C# に表示する方法を定義する Objective-C インターフェイス定義として記述されます。 このプロセスには、インターフェイス宣言と、API コントラクトに必要な基本的な型定義の組み合わせが含まれます。 バインドの種類の概要については、コンパニオン ガイド「 バインド Objective-C ライブラリ」を参照してください。

型定義

構文:

[BaseType (typeof (BTYPE))
interface MyType : [Protocol1, Protocol2] {
     IntPtr Constructor (string foo);
}

属性を持つコントラクト定義内のすべてのインターフェイスは [BaseType] 、生成されたオブジェクトの基本型を宣言します。 上記の宣言では、 というMyType名前のMyType型にバインドするクラス C# 型がObjective-C生成されます。

インターフェイス継承構文を使用して typename の後に型を指定した場合 (上 Protocol1 のサンプルと Protocol2) は、 のコントラクト MyTypeの一部であるかのように、それらのインターフェイスの内容がインライン化されます。 Xamarin.iOS がプロトコルを採用する方法は、プロトコルで宣言されたすべてのメソッドとプロパティを型自体にインライン化することです。

の宣言UITextFieldを Objective-C Xamarin.iOS コントラクトで定義する方法を次に示します。

@interface UITextField : UIControl <UITextInput> {

}

次のように C# API コントラクトとして記述します。

[BaseType (typeof (UIControl))]
interface UITextField : UITextInput {
}

インターフェイスに他の属性を適用し、 属性を構成することで、コード生成の他の多くの側面を [BaseType] 制御できます。

イベントの生成

Xamarin.iOS と Xamarin.Mac API の設計の 1 つの機能は、デリゲート クラスを C# イベントとコールバックとしてマップ Objective-C することです。 ユーザーは、プログラミング パターンを採用Objective-Cするか、ランタイムが呼び出すさまざまなメソッドObjective-Cを実装するクラスのインスタンスなどのDelegateプロパティに割り当てるか、C#スタイルのイベントとプロパティを選択することで、インスタンスごとに選択できます。

モデルの使用方法の 1 つの例を Objective-C 見てみましょう。

bool MakeDecision ()
{
    return true;
}

void Setup ()
{
     var scrollView = new UIScrollView (myRect);
     scrollView.Delegate = new MyScrollViewDelegate ();
     ...
}

class MyScrollViewDelegate : UIScrollViewDelegate {
    public override void Scrolled (UIScrollView scrollView)
    {
        Console.WriteLine ("Scrolled");
    }

    public override bool ShouldScrollToTop (UIScrollView scrollView)
    {
        return MakeDecision ();
    }
}

上記の例では、2 つのメソッドを上書きすることを選択していることがわかります。1 つはスクロール イベントが発生したことを示す通知、もう 1 つは上部にスクロールするかどうかを示すブール値を scrollView 返すコールバックです。

C# モデルを使用すると、ライブラリのユーザーは、C# イベント構文またはプロパティ構文を使用して通知をリッスンし、値を返す必要があるコールバックをフックできます。

同じ機能の C# コードは、ラムダの使用のようになります。

void Setup ()
{
    var scrollview = new UIScrollView (myRect);
    // Event connection, use += and multiple events can be connected
    scrollView.Scrolled += (sender, eventArgs) { Console.WriteLine ("Scrolled"); }

    // Property connection, use = only a single callback can be used
    scrollView.ShouldScrollToTop = (sv) => MakeDecision ();
}

イベントは値を返さない (void 戻り値の型を持つ) ため、複数のコピーを接続できます。 ShouldScrollToTopはイベントではなく、このシグネチャを持つ型UIScrollViewConditionを持つプロパティです。

public delegate bool UIScrollViewCondition (UIScrollView scrollView);

値が bool 返されます。この場合、ラムダ構文を使用すると、関数から MakeDecision 値を返すことができます。

バインディング ジェネレーターでは、 などのUIScrollViewクラスを にUIScrollViewDelegateリンクするイベントとプロパティの生成がサポートされています (これらの Model クラスも呼び出します)。これは、 パラメーターと Delegates パラメーターを使用して定義に注釈を[BaseType]Eventsけることで行われます (後述)。 これらのパラメーターで に [BaseType] 注釈を付けるだけでなく、いくつかのコンポーネントをジェネレーターに通知する必要があります。

複数のパラメーターを受け取るイベントの場合 ( Objective-C 規約では、デリゲート クラスの最初のパラメーターは sender オブジェクトのインスタンスです)、生成される EventArgs クラスの名前を指定する必要があります。 これは、Model クラスの [EventArgs] メソッド宣言の 属性を使用して行われます。 次に例を示します。

[BaseType (typeof (UINavigationControllerDelegate))]
[Model][Protocol]
public interface UIImagePickerControllerDelegate {
    [Export ("imagePickerController:didFinishPickingImage:editingInfo:"), EventArgs ("UIImagePickerImagePicked")]
    void FinishedPickingImage (UIImagePickerController picker, UIImage image, NSDictionary editingInfo);
}

上記の宣言では、 からEventArgs派生する クラスが生成UIImagePickerImagePickedEventArgsされ、 パラメーターと パラメーターの両方がUIImageパックされますNSDictionary。 ジェネレーターによって次の結果が生成されます。

public partial class UIImagePickerImagePickedEventArgs : EventArgs {
    public UIImagePickerImagePickedEventArgs (UIImage image, NSDictionary editingInfo);
    public UIImage Image { get; set; }
    public NSDictionary EditingInfo { get; set; }
}

次に、 クラスで次を UIImagePickerController 公開します。

public event EventHandler<UIImagePickerImagePickedEventArgs> FinishedPickingImage { add; remove; }

値を返すモデル メソッドは、バインド方法が異なります。 これらは、生成された C# デリゲートの名前 (メソッドのシグネチャ) と、ユーザーが自身で実装を提供しない場合に返される既定値の両方を必要とします。 たとえば、 ShouldScrollToTop 定義は次のようになります。

[BaseType (typeof (NSObject))]
[Model][Protocol]
public interface UIScrollViewDelegate {
    [Export ("scrollViewShouldScrollToTop:"), DelegateName ("UIScrollViewCondition"), DefaultValue ("true")]
    bool ShouldScrollToTop (UIScrollView scrollView);
}

上記では、上に示したシグネチャを持つデリゲートが作成 UIScrollViewCondition され、ユーザーが実装を提供しない場合、戻り値は true になります。

属性に [DefaultValue] 加えて、ジェネレーターに指示する 属性を [DefaultValueFromArgument] 使用して、呼び出しで指定されたパラメーターの値を返したり [NoDefaultValue] 、ジェネレーターに既定値がないことを指示するパラメーターを返したりすることもできます。

BaseTypeAttribute

構文:

public class BaseTypeAttribute : Attribute {
        public BaseTypeAttribute (Type t);

        // Properties
        public Type BaseType { get; set; }
        public string Name { get; set; }
        public Type [] Events { get; set; }
        public string [] Delegates { get; set; }
        public string KeepRefUntil { get; set; }
}

BaseType.Name

プロパティを Name 使用して、この型がワールド内でバインドする名前を Objective-C 制御します。 これは通常、C# の型に、.NET Framework設計ガイドラインに準拠しているが、その規則に従っていない のObjective-C名前にマップされる名前を指定するために使用されます。

たとえば、次の場合、.NET Frameworkデザイン ガイドラインでは "URL" ではなく "Url" を使用するため、 型NSUrlConnectionを にマップObjective-CNSURLConnectionします。

[BaseType (typeof (NSObject), Name="NSURLConnection")]
interface NSUrlConnection {
}

指定した名前は、バインドで生成された [Register] 属性の値として使用されます。 が指定されていない場合 Name 、生成された出力の属性の値 [Register] として型の短い名前が使用されます。

BaseType.Events と BaseType.Delegates

これらのプロパティは、生成されたクラスで C#スタイルのイベントの生成を促進するために使用されます。 これらは、特定のクラスをデリゲート クラスに Objective-C リンクするために使用されます。 クラスがデリゲート クラスを使用して通知とイベントを送信する場合は、多くの場合に発生します。 たとえば、 には BarcodeScanner コンパニオン BardodeScannerDelegate クラスがあります。 クラスにはBarcodeScanner通常、 のBarcodeScannerDelegateインスタンスを割り当てるプロパティが含まれますが、これは機能しますが、C#のようなスタイルのイベント インターフェイスをユーザーに公開する場合があります。そのような場合は、 属性の プロパティと Delegates プロパティを[BaseType]使用Eventsします。Delegate

これらのプロパティは常に一緒に設定され、同じ数の要素を持ち、同期を維持する必要があります。配列には Delegates 、ラップする弱く型指定されたデリゲートごとに 1 つの文字列が含まれており Events 、配列には関連付ける型ごとに 1 つの型が含まれています。

[BaseType (typeof (NSObject),
           Delegates=new string [] { "WeakDelegate" },
           Events=new Type [] {typeof(UIAccelerometerDelegate)})]
public interface UIAccelerometer {
}

[BaseType (typeof (NSObject))]
[Model][Protocol]
public interface UIAccelerometerDelegate {
}

BaseType.KeepRefUntil

このクラスの新しいインスタンスが作成されるときにこの属性を適用すると、 によって KeepRefUntil 参照されるメソッドが呼び出されるまで、そのオブジェクトのインスタンスが保持されます。 これは、ユーザーがコードを使用するためにオブジェクトへの参照を保持しないようにする場合に、API の使いやすさを向上させるのに役立ちます。 このプロパティの値は クラス内Delegateのメソッドの名前であるため、 プロパティと Delegates プロパティを組み合わせてEvents使用する必要があります。

次の例は、Xamarin.iOS でこれがどのように使用 UIActionSheet されるかを示しています。

[BaseType (typeof (NSObject), KeepRefUntil="Dismissed")]
[BaseType (typeof (UIView),
           KeepRefUntil="Dismissed",
           Delegates=new string [] { "WeakDelegate" },
           Events=new Type [] {typeof(UIActionSheetDelegate)})]
public interface UIActionSheet {
}

[BaseType (typeof (NSObject))]
[Model][Protocol]
public interface UIActionSheetDelegate {
    [Export ("actionSheet:didDismissWithButtonIndex:"), EventArgs ("UIButton")]
    void Dismissed (UIActionSheet actionSheet, nint buttonIndex);
}

DesignatedDefaultCtorAttribute

この属性がインターフェイス定義に適用されると、セレクターにマップされる既定の (生成された) コンストラクターに属性がinit生成[DesignatedInitializer]されます。

DisableDefaultCtorAttribute

この属性がインターフェイス定義に適用されると、ジェネレーターが既定のコンストラクターを生成できなくなります。

クラス内の他のコンストラクターのいずれかでオブジェクトを初期化する必要がある場合は、この属性を使用します。

PrivateDefaultCtorAttribute

この属性がインターフェイス定義に適用されると、既定のコンストラクターにプライベートとしてフラグが設定されます。 つまり、拡張ファイルから内部的にこのクラスのオブジェクトをインスタンス化することはできますが、クラスのユーザーはアクセスできません。

CategoryAttribute

カテゴリをバインドObjective-Cし、それらを C# 拡張メソッドとして公開して機能を公開する方法Objective-Cをミラーするには、型定義でこの属性を使用します。

カテゴリは、クラスで Objective-C 使用できる一連のメソッドとプロパティを拡張するために使用されるメカニズムです。 実際には、特定のフレームワークが でリンクされている場合 (たとえば NSObject) に基底クラスの機能を拡張し、 UIKitそのメソッドを使用できるようにしますが、新しいフレームワークがリンクされている場合にのみ使用されます。 それ以外の場合は、機能別にクラス内の機能を整理するために使用されます。 これらは、C# 拡張メソッドに似ています。

これは、 のカテゴリのようになります Objective-C。

@interface UIView (MyUIViewExtension)
-(void) makeBackgroundRed;
@end

上記の例は、 メソッド makeBackgroundRedを使用して のUIViewインスタンスを拡張するライブラリにあります。

それらをバインドするには、インターフェイス定義で [Category] 属性を使用できます。 属性を [Category] 使用する場合、属性の [BaseType] 意味は、拡張する基底クラスを指定するために使用されることから、拡張する型に変わります。

次に、拡張機能を UIView バインドし、C# 拡張メソッドに変換する方法を示します。

[BaseType (typeof (UIView))]
[Category]
interface MyUIViewExtension {
    [Export ("makeBackgroundRed")]
    void MakeBackgroundRed ();
}

上記では、拡張メソッドを MyUIViewExtension 含むクラスが MakeBackgroundRed 作成されます。 つまり、任意UIViewのサブクラスで を呼び出MakeBackgroundRedすようになり、 でObjective-C使用するのと同じ機能が提供されます。

次の例のように、カテゴリ内に 静的 メンバーが見つかる場合があります。

@interface FooObject (MyFooObjectExtension)
+ (BOOL)boolMethod:(NSRange *)range;
@end

これにより、カテゴリ C# インターフェイス定義が 正しく なくなります。

[Category]
[BaseType (typeof (FooObject))]
interface FooObject_Extensions {

    // Incorrect Interface definition
    [Static]
    [Export ("boolMethod:")]
    bool BoolMethod (NSRange range);
}

これは、インスタンスFooObjectが必要な拡張機能をBoolMethod使用するが、ObjC 静的拡張機能をバインドしているために正しくありません。これは、C# 拡張メソッドの実装方法に起因する副作用です。

上記の定義を使用する唯一の方法は、次の醜いコードです。

(null as FooObject).BoolMethod (range);

これを回避するための推奨事項は、インターフェイス定義自体内の定義をBoolMethodFooObjectインライン化することです。これにより、意図FooObject.BoolMethod (range)したとおりにこの拡張機能を呼び出すことができます。

[BaseType (typeof (NSObject))]
interface FooObject {

    [Static]
    [Export ("boolMethod:")]
    bool BoolMethod (NSRange range);
}

定義内でメンバーが見つかるたびに警告 (BI1117) を[Static][Category]発行します。 実際に定義内[Category]にメンバーを含める場合は[Static]、 を使用[Category (allowStaticMembers: true)]するか、メンバー定義または[Category]インターフェイス定義を で[Internal]修飾することで、警告を無音にすることができます。

StaticAttribute

この属性がクラスに適用されると、静的クラス (から NSObject派生していないクラス) が生成されるだけなので、 [BaseType] 属性は無視されます。 静的クラスは、公開する C パブリック変数をホストするために使用されます。

次に例を示します。

[Static]
interface CBAdvertisement {
    [Field ("CBAdvertisementDataServiceUUIDsKey")]
    NSString DataServiceUUIDsKey { get; }

次の API を使用して C# クラスを生成します。

public partial class CBAdvertisement  {
    public static NSString DataServiceUUIDsKey { get; }
}

プロトコル/モデル定義

通常、モデルはプロトコルの実装で使用されます。 これらは、実際に上書きされたメソッドにのみランタイムが登録 Objective-C される点で異なります。 それ以外の場合、メソッドは登録されません。

これは一般に、 でフラグが設定 ModelAttributeされているクラスをサブクラス化するときに、基本メソッドを呼び出すべきではありません。 そのメソッドを呼び出すと、次の例外がスローされます: Foundation.You_Should_Not_Call_base_In_This_Method。 オーバーライドするすべてのメソッドに対して、サブクラスで動作全体を実装する必要があります。

AbstractAttribute

既定では、プロトコルの一部であるメンバーは必須ではありません。 これにより、ユーザーは C# の Model クラスから派生し、関心のあるメソッドのみをオーバーライドするだけで、 オブジェクトのサブクラスを作成できます。 コントラクトでは、Objective-Cユーザーがこのメソッドの実装を提供する必要がある場合があります (これらは、 の Objective-Cディレクティブでフラグが設定@requiredされます)。 このような場合は、 属性を使用してこれらのメソッドにフラグを設定する [Abstract] 必要があります。

属性は [Abstract] 、メソッドまたはプロパティのいずれかに適用でき、生成されたメンバーに抽象としてフラグを設定し、 クラスを抽象クラスにします。

Xamarin.iOS から次の情報を取得します。

[BaseType (typeof (NSObject))]
[Model][Protocol]
public interface UITableViewDataSource {
    [Export ("tableView:numberOfRowsInSection:")]
    [Abstract]
    nint RowsInSection (UITableView tableView, nint section);
}

DefaultValueAttribute

ユーザーが Model オブジェクトでこの特定のメソッドのメソッドを指定しない場合に、モデル メソッドによって返される既定値を指定します

構文:

public class DefaultValueAttribute : Attribute {
        public DefaultValueAttribute (object o);
        public object Default { get; set; }
}

たとえば、クラスの次の虚数デリゲート クラスでは、 クラスCameraのプロパティとして公開される をCamera提供ShouldUploadToServerします。 クラスのユーザーが Camera 、true または false に応答できるラムダに値を明示的に設定しない場合、この場合の既定値の戻り値は false になり、 属性で DefaultValue 指定した値になります。

[BaseType (typeof (NSObject))]
[Model][Protocol]
interface CameraDelegate {
    [Export ("camera:shouldPromptForAction:"), DefaultValue (false)]
    bool ShouldUploadToServer (Camera camera, CameraAction action);
}

ユーザーが虚数クラスにハンドラーを設定した場合、この値は無視されます。

var camera = new Camera ();
camera.ShouldUploadToServer = (camera, action) => return SomeDecision ();

参照: [NoDefaultValue][DefaultValueFromArgument]

DefaultValueFromArgumentAttribute

構文:

public class DefaultValueFromArgumentAttribute : Attribute {
    public DefaultValueFromArgumentAttribute (string argument);
    public string Argument { get; }
}

モデル クラスの値を返すメソッドで指定された場合、この属性は、ユーザーが独自のメソッドまたはラムダを指定しなかった場合に、指定されたパラメーターの値を返すようにジェネレーターに指示します。

例:

[BaseType (typeof (NSObject))]
[Model][Protocol]
public interface NSAnimationDelegate {
    [Export ("animation:valueForProgress:"), DelegateName ("NSAnimationProgress"), DefaultValueFromArgumentAttribute ("progress")]
    float ComputeAnimationCurve (NSAnimation animation, nfloat progress);
}

上記の場合、クラスの NSAnimation ユーザーが C# イベント/プロパティのいずれかを使用することを選択し、メソッドまたはラムダに設定 NSAnimation.ComputeAnimationCurve しなかった場合、戻り値は progress パラメーターで渡された値になります。

参照: [NoDefaultValue][DefaultValue]

IgnoredInDelegateAttribute

Model クラスからホスト クラスにイベントまたはデリゲート プロパティを公開しないことが理にかなっている場合があるため、この属性を追加すると、この属性で修飾されたメソッドが生成されないようにジェネレーターに指示されます。

[BaseType (typeof (UINavigationControllerDelegate))]
[Model][Protocol]
public interface UIImagePickerControllerDelegate {
    [Export ("imagePickerController:didFinishPickingImage:editingInfo:"), EventArgs ("UIImagePickerImagePicked")]
    void FinishedPickingImage (UIImagePickerController picker, UIImage image, NSDictionary editingInfo);

    [Export ("imagePickerController:didFinishPickingImage:"), IgnoredInDelegate)] // No event generated for this method
    void FinishedPickingImage (UIImagePickerController picker, UIImage image);
}

DelegateNameAttribute

この属性は、使用するデリゲートシグネチャの名前を設定するために値を返す Model メソッドで使用されます。

例:

[BaseType (typeof (NSObject))]
[Model][Protocol]
public interface NSAnimationDelegate {
    [Export ("animation:valueForProgress:"), DelegateName ("NSAnimationProgress"), DefaultValueFromArgumentAttribute ("progress")]
    float ComputeAnimationCurve (NSAnimation animation, float progress);
}

上記の定義では、ジェネレーターは次のパブリック宣言を生成します。

public delegate float NSAnimationProgress (MonoMac.AppKit.NSAnimation animation, float progress);

DelegateApiNameAttribute

この属性は、ジェネレーターがホスト クラスで生成されたプロパティの名前を変更できるようにするために使用されます。 場合によっては、Delegate クラスに対して FooDelegate クラス メソッドの名前が理にかなっているが、ホスト クラスではプロパティとして奇数に見える場合に便利です。

また、FooDelegate クラスのように名前を付けて保持するのが理にかなっているオーバーロード メソッドが 2 つ以上あるが、より適切な名前でホスト クラスで公開したい場合は、これが本当に便利です (必要です)。

例:

[BaseType (typeof (NSObject))]
[Model][Protocol]
public interface NSAnimationDelegate {
    [Export ("animation:valueForProgress:"), DelegateApiName ("ComputeAnimationCurve"), DelegateName ("Func<NSAnimation, float, float>"), DefaultValueFromArgument ("progress")]
    float GetValueForProgress (NSAnimation animation, float progress);
}

上記の定義では、ジェネレーターはホスト クラスで次のパブリック宣言を生成します。

public Func<NSAnimation, float, float> ComputeAnimationCurve { get; set; }

EventArgsAttribute

複数のパラメーターを受け取るイベント ( Objective-C 規約では、デリゲート クラスの最初のパラメーターが sender オブジェクトのインスタンスである) の場合は、生成される EventArgs クラスに使用する名前を指定する必要があります。 これは、クラスの [EventArgs] メソッド宣言の 属性を使用して Model 行われます。

次に例を示します。

[BaseType (typeof (UINavigationControllerDelegate))]
[Model][Protocol]
public interface UIImagePickerControllerDelegate {
    [Export ("imagePickerController:didFinishPickingImage:editingInfo:"), EventArgs ("UIImagePickerImagePicked")]
    void FinishedPickingImage (UIImagePickerController picker, UIImage image, NSDictionary editingInfo);
}

上記の宣言では、EventArgs から派生したクラスが生成 UIImagePickerImagePickedEventArgs され、 パラメーターと パラメーターの両方が UIImage パックされます NSDictionary。 ジェネレーターによって次の結果が生成されます。

public partial class UIImagePickerImagePickedEventArgs : EventArgs {
    public UIImagePickerImagePickedEventArgs (UIImage image, NSDictionary editingInfo);
    public UIImage Image { get; set; }
    public NSDictionary EditingInfo { get; set; }
}

次に、 クラスで次を UIImagePickerController 公開します。

public event EventHandler<UIImagePickerImagePickedEventArgs> FinishedPickingImage { add; remove; }

EventNameAttribute

この属性は、 クラスで生成されたイベントまたはプロパティの名前をジェネレーターが変更できるようにするために使用されます。 モデル クラスに対して Model クラス メソッドの名前が理にかなっているが、元のクラスではイベントまたはプロパティとして奇数に見える場合に便利な場合があります。

たとえば、 では UIWebView 、 の次のビットが使用されます UIWebViewDelegate

[Export ("webViewDidFinishLoad:"), EventArgs ("UIWebView"), EventName ("LoadFinished")]
void LoadingFinished (UIWebView webView);

上記では、 の メソッドとして を公開していますがLoadFinished、 内UIWebViewDelegateUIWebViewフックするイベントとして を公開LoadingFinishedしています。

var webView = new UIWebView (...);
webView.LoadFinished += delegate { Console.WriteLine ("done!"); }

ModelAttribute

コントラクト API の型定義に 属性を適用 [Model] すると、ユーザーが クラス内のメソッドを上書きした場合にのみ、 クラス内のメソッドへの呼び出しを表示する特別なコードがランタイムによって生成されます。 この属性は、通常、デリゲート クラスをラップ Objective-C するすべての API に適用されます。

NoDefaultValueAttribute

モデルの メソッドが既定の戻り値を提供しないことを指定します。

これは、ランタイム要求にObjective-CObjective-C応答falseして、指定されたセレクターがこのクラスに実装されているかどうかを判断することで、ランタイムで機能します。

[BaseType (typeof (NSObject))]
[Model][Protocol]
interface CameraDelegate {
    [Export ("shouldDisplayPopup"), NoDefaultValue]
    bool ShouldUploadToServer ();
}

参照: [DefaultValue][DefaultValueFromArgument]

プロトコル

プロトコルの概念は Objective-C 、実際には C# には存在しません。 プロトコルは C# インターフェイスに似ていますが、プロトコルで宣言されているすべてのメソッドとプロパティが、それを採用するクラスによって実装される必要があるわけではない点で異なります。 代わりに、一部のメソッドとプロパティは省略可能です。

一般的に、一部のプロトコルは Model クラスとして使用され、 属性を [Model] 使用してバインドする必要があります。

[BaseType (typeof (NSObject))]
[Model, Protocol]
interface MyProtocol {
    // Use [Abstract] when the method is defined in the @required section
    // of the protocol definition in Objective-C
    [Abstract]
    [Export ("say:")]
    void Say (string msg);

    [Export ("listen")]
    void Listen ();
}

Xamarin.iOS 7.0 以降では、新しく改善されたプロトコル バインド機能が組み込まれています。 属性を含む [Protocol] 定義では、実際には 3 つのサポート クラスが生成され、プロトコルの使用方法が大幅に向上します。

// Full method implementation, contains all methods
class MyProtocol : IMyProtocol {
    public void Say (string msg);
    public void Listen (string msg);
}

// Interface that contains only the required methods
interface IMyProtocol: INativeObject, IDisposable {
    [Export ("say:")]
    void Say (string msg);
}

// Extension methods
static class IMyProtocol_Extensions {
    public static void Optional (this IMyProtocol this, string msg);
    }
}

クラスの実装では、 の個々のメソッドをオーバーライドし、完全な型セーフを取得できる完全な抽象クラスが提供されます。 ただし、C# では複数の継承がサポートされていないため、異なる基底クラスが必要になる場合がありますが、インターフェイスを実装する必要があるシナリオもあります。

ここで、生成された インターフェイス定義 が入ってくるのです。 これは、プロトコルから必要なすべてのメソッドを持つインターフェイスです。 これにより、プロトコルを実装する開発者は、インターフェイスを実装するだけです。 ランタイムは、プロトコルを採用するように型を自動的に登録します。

インターフェイスには必要なメソッドのみが一覧表示され、省略可能なメソッドが公開されていることに注意してください。 つまり、プロトコルを採用するクラスは、必要なメソッドの完全な型チェックを受け取りますが、オプションのプロトコル メソッドの弱い型指定 (Export 属性を手動で使用し、シグネチャに一致させる) に頼る必要があります。

プロトコルを使用する API を簡単に使用できるようにするために、バインディング ツールでは、すべての省略可能なメソッドを公開する extensions メソッド クラスも生成されます。 つまり、API を使用している限り、プロトコルはすべてのメソッドを持つものとして扱えることになります。

API でプロトコル定義を使用する場合は、API 定義にスケルトンの空のインターフェイスを記述する必要があります。 API で MyProtocol を使用する場合は、次の操作を行う必要があります。

[BaseType (typeof (NSObject))]
[Model, Protocol]
interface MyProtocol {
    // Use [Abstract] when the method is defined in the @required section
    // of the protocol definition in Objective-C
    [Abstract]
    [Export ("say:")]
    void Say (string msg);

    [Export ("listen")]
    void Listen ();
}

interface IMyProtocol {}

[BaseType (typeof(NSObject))]
interface MyTool {
    [Export ("getProtocol")]
    IMyProtocol GetProtocol ();
}

バインド時 IMyProtocol に が存在しないため、上記が必要です。そのため、空のインターフェイスを指定する必要があります。

プロトコルで生成されたインターフェイスの採用

次のように、プロトコル用に生成されたインターフェイスの 1 つを実装するたびに、

class MyDelegate : NSObject, IUITableViewDelegate {
    nint IUITableViewDelegate.GetRowHeight (nint row) {
        return 1;
    }
}

必要なインターフェイス メソッドの実装は、適切な名前でエクスポートされるため、次のようになります。

class MyDelegate : NSObject, IUITableViewDelegate {
    [Export ("getRowHeight:")]
    nint IUITableViewDelegate.GetRowHeight (nint row) {
        return 1;
    }
}

これは、必要なすべてのプロトコル メンバーに対して機能しますが、省略可能なセレクターに注意する特別なケースがあります。

オプションのプロトコル メンバーは、基底クラスを使用する場合と同じように扱われます。

public class UrlSessionDelegate : NSUrlSessionDownloadDelegate {
	public override void DidWriteData (NSUrlSession session, NSUrlSessionDownloadTask downloadTask, long bytesWritten, long totalBytesWritten, long totalBytesExpectedToWrite)

ただし、プロトコル インターフェイスを使用する場合は、[エクスポート] を追加する必要があります。 IDE は、オーバーライドから追加するときに、オートコンプリートを介して追加します。

public class UrlSessionDelegate : NSObject, INSUrlSessionDownloadDelegate {
	[Export ("URLSession:downloadTask:didWriteData:totalBytesWritten:totalBytesExpectedToWrite:")]
	public void DidWriteData (NSUrlSession session, NSUrlSessionDownloadTask downloadTask, long bytesWritten, long totalBytesWritten, long totalBytesExpectedToWrite)

実行時の 2 つの動作には若干の違いがあります。

  • 基本クラス (例では NSUrlSessionDownloadDelegate) のユーザーは、必要なすべてのセレクターと省略可能なセレクターを提供し、適切な既定値を返します。
  • インターフェイスのユーザー (例では INSUrlSessionDownloadDelegate) は、指定された正確なセレクターにのみ応答します。

ここでは、一部のまれなクラスの動作が異なる場合があります。 しかし、ほとんどの場合、どちらを使用しても安全です。

プロトコルインライン展開

プロトコルを採用すると宣言されている既存 Objective-C の型をバインドする場合は、プロトコルを直接インライン化する必要があります。 これを行うには、属性なしで [BaseType] プロトコルをインターフェイスとして宣言し、インターフェイスの基本インターフェイスの一覧にプロトコルを一覧表示するだけです。

例:

interface SpeakProtocol {
    [Export ("say:")]
    void Say (string msg);
}

[BaseType (typeof (NSObject))]
interface Robot : SpeakProtocol {
    [Export ("awake")]
    bool Awake { get; set; }
}

メンバー定義

このセクションの属性は、型の個々のメンバー (プロパティとメソッド宣言) に適用されます。

AlignAttribute

プロパティの戻り値の型の配置値を指定するために使用します。 特定のプロパティは、特定の境界に配置する必要があるアドレスへのポインターを受け取ります (Xamarin.iOS では、これはたとえば、16 バイトのアラインが必要な一部 GLKBaseEffect のプロパティで発生します)。 このプロパティを使用してゲッターを装飾し、配置値を使用できます。 これは通常、API と統合されている場合、 OpenTK.Vector4 型と OpenTK.Matrix4 型で Objective-C 使用されます。

例:

public interface GLKBaseEffect {
    [Export ("constantColor")]
    Vector4 ConstantColor { [Align (16)] get; set;  }
}

AppearanceAttribute

属性は [Appearance] 、外観マネージャーが導入された iOS 5 に制限されています。

属性は [Appearance] 、フレームワークに参加する任意のメソッドまたはプロパティに UIAppearance 適用できます。 この属性がクラス内のメソッドまたはプロパティに適用されると、バインディング ジェネレーターは、このクラスのすべてのインスタンス、または特定の条件に一致するインスタンスのスタイルを設定するために使用される厳密に型指定された外観クラスを作成するように指示します。

例:

public interface UIToolbar {
    [Since (5,0)]
    [Export ("setBackgroundImage:forToolbarPosition:barMetrics:")]
    [Appearance]
    void SetBackgroundImage (UIImage backgroundImage, UIToolbarPosition position, UIBarMetrics barMetrics);

    [Since (5,0)]
    [Export ("backgroundImageForToolbarPosition:barMetrics:")]
    [Appearance]
    UIImage GetBackgroundImage (UIToolbarPosition position, UIBarMetrics barMetrics);
}

上記では、UIToolbar で次のコードが生成されます。

public partial class UIToolbar {
    public partial class UIToolbarAppearance : UIView.UIViewAppearance {
        public virtual void SetBackgroundImage (UIImage backgroundImage, UIToolbarPosition position, UIBarMetrics barMetrics);
        public virtual UIImage GetBackgroundImage (UIToolbarPosition position, UIBarMetrics barMetrics)
    }
    public static new UIToolbarAppearance Appearance { get; }
    public static new UIToolbarAppearance AppearanceWhenContainedIn (params Type [] containers);
}

AutoReleaseAttribute (Xamarin.iOS 5.4)

[AutoReleaseAttribute] on メソッドと プロパティを使用して、 内の メソッドへのメソッド呼び出しをNSAutoReleasePoolラップします。

では、既定NSAutoReleasePoolの Objective-C に追加される値を返すメソッドがいくつかあります。 既定では、これらはスレッドNSAutoReleasePoolに移動しますが、Xamarin.iOS はマネージド オブジェクトが存続する限りオブジェクトへの参照も保持するため、スレッドが次のスレッドに制御を戻すか、メイン ループに戻るまでしかドレインされない追加の参照NSAutoReleasePoolを に保持したくない場合があります。

この属性は、たとえば、既定の に追加されたオブジェクトを返す重いプロパティ (例: UIImage.FromFile) に適用されます NSAutoReleasePool。 この属性がないと、スレッドがメイン ループに制御を戻さない限り、イメージは保持されます。 Ufあなたのスレッドは、常に生きていると仕事を待っているバックグラウンドダウンローダーのいくつかの並べ替えでした, 画像はリリースされません.

ForcedTypeAttribute

[ForcedTypeAttribute]は、返されたアンマネージ オブジェクトがバインド定義で記述されている型と一致しない場合でも、マネージド型の作成を強制するために使用されます。

これは、ヘッダーで記述されている型がネイティブ メソッドの返された型と一致しない場合に便利です。たとえば、 からNSURLSession次Objective-Cの定義を取ります。

- (NSURLSessionDownloadTask *)downloadTaskWithRequest:(NSURLRequest *)request

インスタンスが返NSURLSessionDownloadTaskされることを明確に示していますが、スーパークラスであり、 にNSURLSessionDownloadTask変換できない をNSURLSessionTaskします。 私たちはタイプセーフなコンテキストにいるので、 InvalidCastException が発生します。

ヘッダーの説明に準拠し、 を InvalidCastException回避するには、 [ForcedTypeAttribute] が使用されます。

[BaseType (typeof (NSObject), Name="NSURLSession")]
interface NSUrlSession {

    [Export ("downloadTaskWithRequest:")]
    [return: ForcedType]
    NSUrlSessionDownloadTask CreateDownloadTask (NSUrlRequest request);
}

では[ForcedTypeAttribute]、 という名前Ownsfalseのブール値も既定[ForcedType (owns: true)]で受け入れられます。 owns パラメーターは、Core Foundation オブジェクトの所有権ポリシーに従うために使用されます。

[ForcedTypeAttribute]は、パラメーター、プロパティ、および戻り値でのみ有効です。

BindAsAttribute

では[BindAsAttribute]、 と NSValueNSString(列挙型) をより正確な C# 型にバインドNSNumberできます。 属性を使用すると、ネイティブ API よりも優れた、より正確な .NET API を作成できます。

メソッド (戻り値)、パラメーター、およびプロパティを で BindAs装飾できます。 唯一の制限は、メンバーが または [Model] インターフェイス内[Protocol]いてはなりません

次に例を示します。

[return: BindAs (typeof (bool?))]
[Export ("shouldDrawAt:")]
NSNumber ShouldDraw ([BindAs (typeof (CGRect))] NSValue rect);

次のように出力されます。

[Export ("shouldDrawAt:")]
bool? ShouldDraw (CGRect rect) { ... }

内部的には、 変換と bool?<<CGRect->NSNumber>NSValue 変換を行います。

現在サポートされているカプセル化の種類は次のとおりです。

  • NSValue
  • NSNumber
  • NSString

NSValue

次の C# データ型は、 から/に NSValueカプセル化することがサポートされています。

  • CGAffineTransform
  • NSRange
  • CGVector
  • SCNMatrix4
  • CLLocationCoordinate2D
  • SCNVector3
  • SCNVector4
  • CGPoint/PointF
  • CGRect/ RectangleF
  • CGSize/SizeF
  • UIEdgeInsets
  • UIOffset
  • MKCoordinateSpan
  • CMTimeRange
  • CMTime
  • CMTimeMapping
  • CATransform3D

NSNumber

次の C# データ型は、 から/に NSNumberカプセル化することがサポートされています。

  • [bool]
  • byte
  • double
  • float
  • short
  • INT
  • long
  • sbyte
  • ushort
  • uint
  • ulong
  • nfloat
  • nint
  • nuint
  • 列挙型

NSString

[BindAs]NSString 定数によってサポートされる列挙型との結合で動作するため、次に例を示すより優れた .NET API を作成できます。

[BindAs (typeof (CAScroll))]
[Export ("supportedScrollMode")]
NSString SupportedScrollMode { get; set; }

次のように出力されます。

[Export ("supportedScrollMode")]
CAScroll SupportedScrollMode { get; set; }

に指定されたenum<列挙型[BindAs]NSString 定数によってサポートされている場合にのみ、 ->NSString 変換を処理します。

配列

[BindAs] では、サポートされている任意の型の配列もサポートされています。例として、次の API 定義を使用できます。

[return: BindAs (typeof (CAScroll []))]
[Export ("getScrollModesAt:")]
NSString [] GetScrollModes ([BindAs (typeof (CGRect []))] NSValue [] rects);

次のように出力されます。

[Export ("getScrollModesAt:")]
CAScroll? [] GetScrollModes (CGRect [] rects) { ... }

パラメーターはrects、 ごとに CGRectNSValue含む にNSArrayカプセル化され、戻り値として、 を含むNSStrings返された のCAScroll?値を使用して作成された の配列をNSArray取得します。

BindAttribute

[Bind]属性には、メソッドまたはプロパティ宣言に適用する場合は 1 つ、プロパティ内の個々のゲッターまたはセッターに適用する場合は 2 つの使用があります。

メソッドまたはプロパティに使用する場合、属性の [Bind] 効果は、指定したセレクターを呼び出すメソッドを生成することです。 ただし、生成されたメソッドは 属性で [Export] 修飾されません。つまり、メソッドのオーバーライドに参加できません。 これは通常、拡張メソッドを [Target] 実装 Objective-C するための 属性と組み合わせて使用されます。

次に例を示します。

public interface UIView {
    [Bind ("drawAtPoint:withFont:")]
    SizeF DrawString ([Target] string str, CGPoint point, UIFont font);
}

getter または setter で使用する場合、 属性は、 [Bind] プロパティのゲッターとセッター Objective-C セレクター名を生成するときにコード ジェネレーターによって推論される既定値を変更するために使用されます。 既定では、 という名前fooBarのプロパティにフラグを設定すると、ジェネレーターはゲッターとsetFooBar:セッターのエクスポートを生成fooBarします。 場合によっては、 Objective-C はこの規則に従いません。通常、ゲッター名は に変更されます isFooBar。 この属性を使用して、ジェネレーターにこのことを通知します。

次に例を示します。

// Default behavior
[Export ("active")]
bool Active { get; set; }

// Custom naming with the Bind attribute
[Export ("visible")]
bool Visible { [Bind ("isVisible")] get; set; }

AsyncAttribute

Xamarin.iOS 6.3 以降でのみ使用できます。

この属性は、完了ハンドラーを最後の引数として受け取るメソッドに適用できます。

属性は、 [Async] 最後の引数がコールバックであるメソッドで使用できます。 これをメソッドに適用すると、バインディング ジェネレーターは サフィックス Asyncを持つそのメソッドのバージョンを生成します。 コールバックがパラメーターを受け取っていない場合、コールバックが パラメーターを Task受け取る場合、戻り値は になります Task<T>

[Export ("upload:complete:")]
[Async]
void LoadFile (string file, NSAction complete)

この非同期メソッドは次のように生成されます。

Task LoadFileAsync (string file);

コールバックが複数のパラメーターを受け取る場合は、 または ResultTypeNameResultType設定して、すべてのプロパティを保持する生成された型の目的の名前を指定する必要があります。

delegate void OnComplete (string [] files, nint byteCount);

[Export ("upload:complete:")]
[Async (ResultTypeName="FileLoading")]
void LoadFiles (string file, OnComplete complete)

次の例では、この非同期メソッドが生成されます。ここでFileLoading、 と の両方filesbyteCountにアクセスするためのプロパティが含まれています。

Task<FileLoading> LoadFile (string file);

コールバックの最後のパラメーターが の場合、NSError値が null でない場合、生成されたAsyncメソッドはチェックし、その場合は、生成された非同期メソッドによってタスク例外が設定されます。

[Export ("upload:onComplete:")]
[Async]
void Upload (string file, Action<string,NSError> onComplete);

上記では、次の非同期メソッドが生成されます。

Task<string> UploadAsync (string file);

また、エラーが発生すると、結果の Task には、結果NSErrorの をラップする にNSErrorException例外が設定されます。

AsyncAttribute.ResultType

このプロパティを使用して、返されるオブジェクトの値を Task 指定します。 このパラメーターは既存の型を受け取ります。そのため、コア API 定義のいずれかで定義する必要があります。

AsyncAttribute.ResultTypeName

このプロパティを使用して、返されるオブジェクトの値を Task 指定します。 このパラメーターは、目的の型名の名前を受け取ります。ジェネレーターは、コールバックが受け取るパラメーターごとに 1 つずつ、一連のプロパティを生成します。

AsyncAttribute.MethodName

生成された非同期メソッドの名前をカスタマイズするには、このプロパティを使用します。 既定では、 メソッドの名前を使用し、"Async" というテキストを追加します。これを使用して、この既定値を変更できます。

DesignatedInitializerAttribute

この属性がコンストラクターに適用されると、最終的なプラットフォーム アセンブリで同じ [DesignatedInitializer] が生成されます。 これは、サブクラスで使用するコンストラクターを IDE が示すのに役立ちます。

これは、 の /clang の使用__attribute__((objc_designated_initializer))にObjective-Cマップする必要があります。

DisableZeroCopyAttribute

この属性は文字列パラメーターまたは文字列プロパティに適用され、このパラメーターに対してゼロ コピー文字列マーシャリングを使用しないようにコード ジェネレーターに指示し、代わりに C# 文字列から新しい NSString インスタンスを作成します。 この属性は、コマンド ライン オプションまたはアセンブリ レベル属性 ZeroCopyStringsAttributeを設定してゼロ コピー文字列マーシャリングを使用--zero-copyするようにジェネレーターに指示した場合にのみ、文字列に必要です。

これは、 プロパティが プロパティではなく または assign プロパティとしてretain宣言されているObjective-C場合にcopy必要です。 これらは通常、開発者によって間違って "最適化" されたサード パーティ製ライブラリで発生します。 一般に、 retain または のユーザー派生クラスNSStringは、ライブラリ コードの知識なしに文字列の内容を変更し、アプリケーションを微妙に壊す可能性があるためNSMutableString、プロパティassignNSStringが正しくありません。 通常、これは早期の最適化が原因で発生します。

の 2 つのそのようなプロパティを次に Objective-C示します。

@property(nonatomic,retain) NSString *name;
@property(nonatomic,assign) NSString *name2;

DisposeAttribute

クラスに を [DisposeAttribute] 適用する場合は、クラスのメソッド実装に Dispose() 追加されるコード スニペットを指定します。

Disposeメソッドは および btouch-native ツールによってbmac-native自動的に生成されるため、 属性を[Dispose]使用して、生成されたDisposeメソッド実装にコードを挿入する必要があります。

次に例を示します。

[BaseType (typeof (NSObject))]
[Dispose ("if (OpenConnections > 0) CloseAllConnections ();")]
interface DatabaseConnection {
}

ExportAttribute

属性は [Export] 、ランタイムに公開されるメソッドまたはプロパティにフラグを設定するために Objective-C 使用されます。 この属性は、バインド ツールと、実際の Xamarin.iOS および Xamarin.Mac ランタイムの間で共有されます。 メソッドの場合、パラメーターは生成されたコードに逐語的に渡されます。プロパティの場合、getter と setter Exports は基本宣言に [BindAttribute] 基づいて生成されます (バインディング ツールの動作を変更する方法については、 のセクションを参照してください)。

構文:

public enum ArgumentSemantic {
    None, Assign, Copy, Retain.
}

[AttributeUsage (AttributeTargets.Method | AttributeTargets.Constructor | AttributeTargets.Property)]
public class ExportAttribute : Attribute {
    public ExportAttribute();
    public ExportAttribute (string selector);
    public ExportAttribute (string selector, ArgumentSemantic semantic);
    public string Selector { get; set; }
    public ArgumentSemantic ArgumentSemantic { get; set; }
}

セレクターは、バインドされている基になるObjective-Cメソッドまたはプロパティの名前を表します。

ExportAttribute.ArgumentSemantic

FieldAttribute

この属性は、C グローバル変数をオンデマンドで読み込まれ、C# コードに公開されるフィールドとして公開するために使用されます。 通常、これは、C または Objective-C で定義されている定数の値を取得するために必要です。これは、一部の API で使用されるトークンであるか、値が不透明であり、ユーザー コードでそのまま使用する必要があります。

構文:

public class FieldAttribute : Attribute {
    public FieldAttribute (string symbolName);
    public FieldAttribute (string symbolName, string libraryName);
    public string SymbolName { get; set; }
    public string LibraryName { get; set; }
}

symbolName 、リンク先の C シンボルです。 既定では、これは、型が定義されている名前空間から名前が推論されるライブラリから読み込まれます。 これがシンボルが検索されるライブラリでない場合は、 パラメーターを渡す libraryName 必要があります。 静的ライブラリをリンクする場合は、 パラメーターとして をlibraryName使用__Internalします。

生成されるプロパティは常に静的です。

Field 属性でフラグが設定されたプロパティには、次の型を指定できます。

  • NSString
  • NSArray
  • nint / int / long
  • nuint / uint / ulong
  • nfloat / float
  • double
  • CGSize
  • System.IntPtr
  • 列挙型

セッターは、 NSString 定数によってサポートされる列挙型ではサポートされていませんが、必要に応じて手動でバインドできます。

例:

[Static]
interface CameraEffects {
     [Field ("kCameraEffectsZoomFactorKey", "CameraLibrary")]
     NSString ZoomFactorKey { get; }
}

InternalAttribute

属性は[Internal]メソッドまたはプロパティに適用でき、生成されたコードinternalに対して C# でフラグを設定キーワード (keyword)、生成されたアセンブリ内のコードに対してのみコードにアクセスできるようにする効果があります。 これは通常、レベルが低すぎる API を非表示にしたり、改善する最適ではないパブリック API を提供したり、ジェネレーターでサポートされておらず、何らかの手コーディングが必要な API に対して使用されます。

バインディングを設計するときは、通常、この属性を使用してメソッドまたはプロパティを非表示にし、メソッドまたはプロパティに別の名前を指定します。次に、C# の補完的なサポート ファイルに、基になる機能を公開する厳密に型指定されたラッパーを追加します。

次に例を示します。

[Internal]
[Export ("setValue:forKey:")]
void _SetValueForKey (NSObject value, NSObject key);

[Internal]
[Export ("getValueForKey:")]
NSObject _GetValueForKey (NSObject key);

次に、サポート ファイルで、次のようなコードを作成できます。

public NSObject this [NSObject idx] {
    get {
        return _GetValueForKey (idx);
    }
    set {
        _SetValueForKey (value, idx);
    }
}

IsThreadStaticAttribute

この属性は、.NET [ThreadStatic] 属性で注釈を付けるプロパティのバッキング フィールドにフラグを設定します。 これは、フィールドがスレッドの静的変数である場合に便利です。

MarshalNativeExceptions (Xamarin.iOS 6.0.6)

この属性により、メソッドはネイティブ (Objective-C) 例外をサポートします。 呼び出しは直接呼び出す objc_msgSend 代わりに、ObjectiveC 例外をキャッチし、マネージド例外にマーシャリングするカスタム トランポリンを経由します。

現時点では、少数 objc_msgSend の署名のみがサポートされていますが (バインドを使用するアプリのネイティブ リンクが不足しているmonotouch__objc_msgSendシンボルで失敗した場合に署名がサポートされていない場合はわかります) 要求に応じてさらに追加できます。

NewAttribute

この属性は、ジェネレーターが宣言の前にキーワード (keyword)をnew生成するために、メソッドとプロパティに適用されます。

これは、基底クラスに既に存在するサブクラスで同じメソッドまたはプロパティ名が導入された場合に、コンパイラの警告を回避するために使用されます。

NotificationAttribute

この属性をフィールドに適用して、ジェネレーターに厳密に型指定されたヘルパー Notifications クラスを生成させることができます。

この属性は、ペイロードを含まない通知の引数なしで使用することも、API 定義内の別のインターフェイスを参照する を指定 System.Type することもできます。通常は、名前は "EventArgs" で終わっています。 ジェネレーターはインターフェイスをサブクラス EventArgs 化するクラスに変換し、そこにリストされているすべてのプロパティを含めます。 [Export]クラスで 属性をEventArgs使用して、値をフェッチするためにディクショナリを検索するために使用されるキーのObjective-C名前を一覧表示する必要があります。

次に例を示します。

interface MyClass {
    [Notification]
    [Field ("MyClassDidStartNotification")]
    NSString DidStartNotification { get; }
}

上記のコードでは、次のメソッドを使用して入れ子になったクラス MyClass.Notifications が生成されます。

public class MyClass {
   [..]
   public Notifications {
      public static NSObject ObserveDidStart (EventHandler<NSNotificationEventArgs> handler)
      public static NSObject ObserveDidStart (NSObject objectToObserve, EventHandler<NSNotificationEventArgs> handler)
   }
}

その後、コードのユーザーは、次のようなコードを使用して 、NSDefaultCenter に投稿された通知を簡単にサブスクライブできます。

var token = MyClass.Notifications.ObserverDidStart ((notification) => {
    Console.WriteLine ("Observed the 'DidStart' event!");
});

または、観察する特定のオブジェクトを設定します。 このメソッドにをobjectToObservenullすと、他のピアと同じように動作します。

var token = MyClass.Notifications.ObserverDidStart (objectToObserve, (notification) => {
    Console.WriteLine ("Observed the 'DidStart' event on objectToObserve!");
});

ObserveDidStart 戻り値を使用すると、次のような通知の受信を簡単に停止できます。

token.Dispose ();

または、 NSNotification.DefaultCenter.RemoveObserver を呼び出してトークンを渡すことができます。 通知にパラメーターが含まれている場合は、次のようにヘルパー EventArgs インターフェイスを指定する必要があります。

interface MyClass {
    [Notification (typeof (MyScreenChangedEventArgs)]
    [Field ("MyClassScreenChangedNotification")]
    NSString ScreenChangedNotification { get; }
}

// The helper EventArgs declaration
interface MyScreenChangedEventArgs {
    [Export ("ScreenXKey")]
    nint ScreenX { get; set; }

    [Export ("ScreenYKey")]
    nint ScreenY { get; set; }

    [Export ("DidGoOffKey")]
    [ProbePresence]
    bool DidGoOff { get; }
}

上記では、 プロパティと ScreenY プロパティをMyScreenChangedEventArgsScreenX持つクラスが生成されます。このクラスは、それぞれキーScreenXKeyを使用して NSNotification.UserInfo ディクショナリからデータをフェッチし、ScreenYKey適切な変換を適用します。 属性は [ProbePresence] 、値を抽出する代わりに、 で UserInfoキーが設定されている場合にジェネレーターがプローブするために使用されます。 これは、キーの存在が値 (通常はブール値の場合) である場合に使用されます。

これにより、次のようなコードを記述できます。

var token = MyClass.NotificationsObserveScreenChanged ((notification) => {
    Console.WriteLine ("The new screen dimensions are {0},{1}", notification.ScreenX, notification.ScreenY);
});

場合によっては、ディクショナリで渡される値に関連付けられた定数が存在しません。 Apple ではパブリック シンボル定数を使用する場合もあれば、文字列定数を使用する場合もあります。 既定では、 [Export] 指定した EventArgs クラスの 属性では、指定した名前がパブリック シンボルとして使用され、実行時に参照されます。 そうでない場合は、代わりに文字列定数として検索し、値を ArgumentSemantic.Assign Export 属性に渡します。

Xamarin.iOS 8.4 の新機能

場合によっては、通知は引数なしで有効期間を開始するため、引数を指定せずに を [Notification] 使用できます。 ただし、通知のパラメーターが導入される場合があります。 このシナリオをサポートするために、 属性を複数回適用できます。

バインディングを開発していて、既存のユーザー コードを壊さないようにしたい場合は、次の場所から既存の通知を有効にします。

interface MyClass {
    [Notification]
    [Field ("MyClassScreenChangedNotification")]
    NSString ScreenChangedNotification { get; }
}

次のように、通知属性を 2 回一覧表示するバージョンに。

interface MyClass {
    [Notification]
    [Notification (typeof (MyScreenChangedEventArgs)]
    [Field ("MyClassScreenChangedNotification")]
    NSString ScreenChangedNotification { get; }
}

NullAllowedAttribute

これがプロパティに適用されると、プロパティに値 null を割り当てることができるようにフラグが設定されます。 これは参照型に対してのみ有効です。

これがメソッド シグネチャのパラメーターに適用されると、指定したパラメーターを null にすることができ、値を渡すためにnullチェックを実行する必要がないことを示します。

参照型にこの属性がない場合、バインド ツールは割り当てられている値のチェックをに渡す前にObjective-C生成し、割り当てられたnull値が の場合に をArgumentNullExceptionスローするチェックを生成します。

次に例を示します。

// In properties

[NullAllowed]
UIImage IconFile { get; set; }

// In methods
void SetImage ([NullAllowed] UIImage image, State forState);

OverrideAttribute

この属性を使用して、この特定のメソッドのバインドにキーワード (keyword)でフラグを設定する必要があることをバインド ジェネレーターにoverride指示します。

PreSnippetAttribute

この属性を使用すると、入力パラメーターが検証された後、コードが に呼び出される前に Objective-C挿入されるコードを挿入できます。

例:

[Export ("demo")]
[PreSnippet ("var old = ViewController;")]
void Demo ();

PrologueSnippetAttribute

この属性を使用すると、生成されたメソッドでパラメーターのいずれかが検証される前に、挿入するコードを挿入できます。

例:

[Export ("demo")]
[Prologue ("Trace.Entry ();")]
void Demo ();

PostGetAttribute

このクラスから指定したプロパティを呼び出して、そこから値をフェッチするようにバインド ジェネレーターに指示します。

このプロパティは、通常、オブジェクト グラフを参照し続けるオブジェクトを参照するキャッシュを更新するために使用されます。 通常、Add/Remove などの操作を含むコードに表示されます。 このメソッドは、要素が追加または削除された後に内部キャッシュを更新して、実際に使用されているオブジェクトへのマネージド参照を確実に保持するために使用されます。 これは、バインディング ツールによって、特定のバインド内のすべての参照オブジェクトのバッキング フィールドが生成されるためです。

例:

[BaseType (typeof (NSObject))]
[Since (4,0)]
public interface NSOperation {
    [Export ("addDependency:")][PostGet ("Dependencies")]
    void AddDependency (NSOperation op);

    [Export ("removeDependency:")][PostGet ("Dependencies")]
    void RemoveDependency (NSOperation op);

    [Export ("dependencies")]
    NSOperation [] Dependencies { get; }
}

この場合、 プロパティは、 Dependencies オブジェクトの NSOperation 依存関係を追加または削除した後に呼び出され、実際に読み込まれたオブジェクトを表すグラフが作成され、メモリ リークとメモリ破損の両方が防止されます。

PostSnippetAttribute

この属性を使用すると、コードが基になる Objective-C メソッドを呼び出した後に挿入される C# ソース コードを挿入できます。

例:

[Export ("demo")]
[PostSnippet ("if (old != null) old.DemoComplete ();")]
void Demo ();

ProxyAttribute

この属性は、プロキシ オブジェクトとしてフラグを設定する値を返すために適用されます。 一部 Objective-C の API は、ユーザー バインドと区別できないプロキシ オブジェクトを返します。 この属性の効果は、オブジェクトにオブジェクトとしてフラグを DirectBinding 設定することです。 Xamarin.Mac のシナリオについては、 このバグに関する説明を参照してください。

RetainListAttribute

パラメーターへのマネージド参照を保持するか、パラメーターへの内部参照を削除するようにジェネレーターに指示します。 これは、オブジェクトの参照を維持するために使用されます。

構文:

public class RetainListAttribute: Attribute {
     public RetainListAttribute (bool doAdd, string listName);
}

doAdd 値が true の場合、 パラメーターが に __mt_{0}_var List<NSObject>;追加されます。 は {0} 、指定 listNameされた に置き換えられます。 このバッキング フィールドは、API に対する補完的な部分クラスで宣言する必要があります。

例については、「foundation.cs」と「NSNotificationCenter.cs」を参照してください。

ReleaseAttribute (Xamarin.iOS 6.0)

これは、オブジェクトを返す前にジェネレーターが を呼び出 Release す必要があることを示す戻り値の型に適用できます。 これは、メソッドが保持オブジェクトを提供する場合にのみ必要です (最も一般的なシナリオである自動リリース オブジェクトとは対照的に)

例:

[Export ("getAndRetainObject")]
[return: Release ()]
NSObject GetAndRetainObject ();

さらに、この属性は生成されたコードに反映されるため、Xamarin.iOS ランタイムは、このような関数から に戻る際に Objective-C オブジェクトを保持する必要があることを認識します。

SealedAttribute

生成されたメソッドにシールとしてフラグを設定するようにジェネレーターに指示します。 この属性を指定しない場合、既定では仮想メソッド (仮想メソッド、抽象メソッド、または他の属性の使用方法に応じたオーバーライド) を生成します。

StaticAttribute

属性が [Static] メソッドまたはプロパティに適用されると、静的メソッドまたはプロパティが生成されます。 この属性が指定されていない場合、ジェネレーターはインスタンス メソッドまたはプロパティを生成します。

TransientAttribute

この属性を使用して、値が一時的であるプロパティ、つまり iOS によって一時的に作成されるが有効期間が長くないオブジェクトにフラグを設定します。 この属性をプロパティに適用すると、ジェネレーターは、このプロパティのバッキング フィールドを作成しません。つまり、マネージド クラスは オブジェクトへの参照を保持しません。

WrapAttribute

Xamarin.iOS/Xamarin.Mac バインドの設計では、 属性を使用して、 [Wrap] 厳密に型指定されたオブジェクトで弱く型指定されたオブジェクトをラップします。 これは主Objective-Cに、型または NSObjectとしてid宣言されるデリゲート オブジェクトで実行されます。 Xamarin.iOS と Xamarin.Mac で使用される規則は、これらのデリゲートまたはデータ ソースを型 NSObject として公開し、規則 "Weak" と公開されている名前を使用して名前を付けます。 の id delegateObjective-C プロパティは、API コントラクト ファイル内のプロパティとして NSObject WeakDelegate { get; set; } 公開されます。

ただし、通常、このデリゲートに割り当てられる値は厳密な型であるため、厳密な型を表示して属性を適用 [Wrap] します。これは、ユーザーが細かい制御が必要な場合や、低レベルのトリックに頼る必要がある場合、またはほとんどの作業に厳密に型指定されたプロパティを使用できる場合に弱い型を使用することを選択できることを意味します。

例:

[BaseType (typeof (NSObject))]
interface Demo {
     [Export ("delegate"), NullAllowed]
     NSObject WeakDelegate { get; set; }

     [Wrap ("WeakDelegate")]
     DemoDelegate Delegate { get; set; }
}

[BaseType (typeof (NSObject))]
[Model][Protocol]
interface DemoDelegate {
    [Export ("doDemo")]
    void DoDemo ();
}

これは、ユーザーが弱く型指定されたバージョンのデリゲートを使用する方法です。

// The weak case, user has to roll his own
class SomeObject : NSObject {
    [Export ("doDemo")]
    void CallbackForDoDemo () {}

}

var demo = new Demo ();
demo.WeakDelegate = new SomeObject ();

これは、ユーザーが厳密に型指定されたバージョンを使用する方法です。ユーザーは C# の型システムを利用し、オーバーライド キーワード (keyword)を使用して意図を宣言しており、ユーザーのバインドでこの作業を行ったので、 を使用してメソッド[Export]を手動で装飾する必要はありません。

// This is the strong case,
class MyDelegate : DemoDelegate {
   override void Demo DoDemo () {}
}

var strongDemo = new Demo ();
demo.Delegate = new MyDelegate ();

属性の [Wrap] もう 1 つの用途は、厳密に型指定されたバージョンのメソッドをサポートすることです。 次に例を示します。

[BaseType (typeof (NSObject))]
interface XyzPanel {
    [Export ("playback:withOptions:")]
    void Playback (string fileName, [NullAllowed] NSDictionary options);

    [Wrap ("Playback (fileName, options == null ? null : options.Dictionary")]
    void Playback (string fileName, XyzOptions options);
}

属性で [Wrap] 修飾された [Category] 型内のメソッドに属性を適用する場合は、拡張メソッドが生成されるため、最初の引数として を含める This 必要があります。 次に例を示します。

[Wrap ("Write (This, image, options?.Dictionary, out error)")]
bool Write (CIImage image, CIImageRepresentationOptions options, out NSError error);

によって[Wrap]生成されるメンバーは既定では行われませんvirtual。メンバーが必要な場合は、省略可能isVirtualvirtualパラメーターにtrue設定できます。

[BaseType (typeof (NSObject))]
interface FooExplorer {
    [Export ("fooWithContentsOfURL:")]
    void FromUrl (NSUrl url);

    [Wrap ("FromUrl (NSUrl.FromString (url))", isVirtual: true)]
    void FromUrl (string url);
}

[Wrap] は、プロパティのゲッターとセッターでも直接使用できます。 これにより、それらを完全に制御し、必要に応じてコードを調整できます。 たとえば、スマート列挙型を使用する次の API 定義を考えてみましょう。

// Smart enum.
enum PersonRelationship {
        [Field (null)]
        None,

        [Field ("FMFather", "__Internal")]
        Father,

        [Field ("FMMother", "__Internal")]
        Mother
}

インターフェイス定義:

// Property definition.

[Export ("presenceType")]
NSString _PresenceType { get; set; }

PersonRelationship PresenceType {
    [Wrap ("PersonRelationshipExtensions.GetValue (_PresenceType)")]
    get;
    [Wrap ("_PresenceType = value.GetConstant ()")]
    set;
}

パラメーター属性

このセクションでは、メソッド定義のパラメーターに適用できる属性と [NullAttribute] 、プロパティ全体に適用される 属性について説明します。

BlockCallback

この属性は、C# デリゲート宣言のパラメーター型に適用され、問題のパラメーターがブロック呼び出し規則に Objective-C 準拠し、この方法でマーシャリングする必要があることをバインダーに通知します。

これは通常、 で次のように定義されているコールバックに Objective-C使用されます。

typedef returnType (^SomeTypeDefinition) (int parameter1, NSString *parameter2);

CCallback も参照してください。

CCallback

この属性は、C# デリゲート宣言のパラメーター型に適用され、問題のパラメーターが C ABI 関数ポインター呼び出し規則に準拠し、この方法でマーシャリングする必要があることをバインダーに通知します。

これは通常、 で次のように定義されているコールバックに Objective-C使用されます。

typedef returnType (*SomeTypeDefinition) (int parameter1, NSString *parameter2);

BlockCallback」も参照してください。

パラメーター

メソッド定義の [Params] 最後の配列パラメーターで 属性を使用して、ジェネレーターに定義に "params" を挿入させることができます。 これにより、バインディングで省略可能なパラメーターを簡単に許可できます。

たとえば、次の定義です。

[Export ("loadFiles:")]
void LoadFiles ([Params]NSUrl [] files);

次のコードを記述できるようにします。

foo.LoadFiles (new NSUrl (url));
foo.LoadFiles (new NSUrl (url1), new NSUrl (url2), new NSUrl (url3));

これは、ユーザーが要素を渡すために配列を純粋に作成する必要がないという利点があります。

PlainString

文字列パラメーターの前で 属性を [PlainString] 使用して、パラメーターを として渡す代わりに、文字列を C 文字列として渡すようにバインド ジェネレーターに NSString指示できます。

ほとんどの Objective-C API はパラメーターを使用NSStringしますが、一部の API ではバリエーションではなく、文字列を渡すための API がNSString公開char *されています。 このような場合は を使用 [PlainString] します。

たとえば、次の宣言を次 Objective-C に示します。

- (void) setText: (NSString *) theText;
- (void) logMessage: (char *) message;

次のようにバインドする必要があります。

[Export ("setText:")]
void SetText (string theText);

[Export ("logMessage:")]
void LogMessage ([PlainString] string theText);

RetainAttribute

指定したパラメーターへの参照を保持するようにジェネレーターに指示します。 ジェネレーターは、このフィールドのバッキング ストアを提供するか、値を格納する名前 ( WrapName) を指定できます。 これは、パラメーター Objective-C として渡されるマネージド オブジェクトへの参照を保持し、オブジェクトのこのコピーのみを保持する Objective-C ことがわかっている場合に便利です。 たとえば、 のような SetDisplay (SomeObject) API では、SetDisplay で一度に 1 つのオブジェクトしか表示できない可能性があるため、この属性を使用します。 複数のオブジェクト (スタックに似た API など) を追跡する必要がある場合は、 属性を [RetainList] 使用します。

構文:

public class RetainAttribute {
    public RetainAttribute ();
    public RetainAttribute (string wrapName);
    public string WrapName { get; }
}

RetainListAttribute

パラメーターへのマネージド参照を保持するか、パラメーターへの内部参照を削除するようにジェネレーターに指示します。 これは、オブジェクトの参照を維持するために使用されます。

構文:

public class RetainListAttribute: Attribute {
     public RetainListAttribute (bool doAdd, string listName);
}

doAdd 値が true の場合、 パラメーターが に __mt_{0}_var List<NSObject>追加されます。 は {0} 、指定 listNameされた に置き換えられます。 このバッキング フィールドは、API に対する補完的な部分クラスで宣言する必要があります。

例については、「foundation.cs」と「NSNotificationCenter.cs」を参照してください。

TransientAttribute

この属性はパラメーターに適用され、 から Objective-C C# に移行する場合にのみ使用されます。 これらの遷移中に、さまざまな Objective-CNSObject パラメーターがオブジェクトのマネージド表現にラップされます。

ランタイムはネイティブ オブジェクトへの参照を受け取り、オブジェクトへの最後のマネージド参照がなくなるまで参照を保持し、GC を実行する機会があります。

場合によっては、C# ランタイムがネイティブ オブジェクトへの参照を保持しないことが重要です。 これは、基になるネイティブ コードがパラメーターのライフサイクルに特別な動作をアタッチした場合に発生することがあります。 たとえば、 パラメーターのデストラクターは、クリーンアップ アクションを実行したり、貴重なリソースを破棄したりします。

この属性は、上書きされたメソッドから に戻るときに、可能であればオブジェクトを破棄することをランタイムに Objective-C 通知します。

ルールは単純です。ランタイムがネイティブ オブジェクトから新しいマネージド表現を作成する必要がある場合、関数の最後にネイティブ オブジェクトの保持カウントが削除され、マネージド オブジェクトの Handle プロパティがクリアされます。 つまり、マネージド オブジェクトへの参照を保持すると、その参照は役に立たなくなります (その参照でメソッドを呼び出すと例外がスローされます)。

渡されたオブジェクトが作成されていない場合、またはオブジェクトの未処理のマネージド表現が既に存在する場合、強制破棄は行われません。

[プロパティ属性]

NotImplementedAttribute

この属性は、getter を Objective-C 持つプロパティが基底クラスで導入され、変更可能なサブクラスによってセッターが導入されるイディオムをサポートするために使用されます。

C# ではこのモデルがサポートされていないため、基底クラスにはセッターとゲッターの両方が必要であり、サブクラスでは OverrideAttribute を使用できます。

この属性は、プロパティ セッターでのみ使用され、 で変更可能なイディオム Objective-Cをサポートするために使用されます。

例:

[BaseType (typeof (NSObject))]
interface MyString {
    [Export ("initWithValue:")]
    IntPtr Constructor (string value);

    [Export ("value")]
    string Value {
        get;

    [NotImplemented ("Not available on MyString, use MyMutableString to set")]
        set;
    }
}

[BaseType (typeof (MyString))]
interface MyMutableString {
    [Export ("value")]
    [Override]
    string Value { get; set; }
}

列挙型属性

定数を列挙型値にマッピング NSString することは、より優れた .NET API を作成するための簡単な方法です。 それでは次のことが行われます。

  • を使用すると、API の正しい値 のみを 表示することで、コード補完がより便利になります。
  • は型の安全性を追加します。正しくないコンテキストで別 NSString の定数を使用することはできません。
  • を使用すると、一部の定数を非表示にして、コード補完機能を失うことなく短い API リストを表示できます。

例:

enum NSRunLoopMode {

    [DefaultEnumValue]
    [Field ("NSDefaultRunLoopMode")]
    Default,

    [Field ("NSRunLoopCommonModes")]
    Common,

    [Field (null)]
    Other = 1000
}

上記のバインド定義から、ジェネレーターは自身をenum作成し、列挙型の値とNSString定数の間に 2 つの方法変換メソッドを含む静的型も作成*Extensionsします。 つまり、定数が API に含まれていない場合でも、開発者は定数を引き続き使用できます。

例 :

// using the NSString constant in a different API / framework / 3rd party code
CallApiRequiringAnNSString (NSRunLoopMode.Default.GetConstant ());
// converting the constants from a different API / framework / 3rd party code
var constant = CallApiReturningAnNSString ();
// back into an enum value
CallApiWithEnum (NSRunLoopModeExtensions.GetValue (constant));

DefaultEnumValueAttribute

この属性を使用して 、1 つの 列挙値を装飾できます。 列挙型の値が不明な場合、これは返される定数になります。

上記の例から:

var x = (NSRunLoopMode) 99;
Call (x.GetConstant ()); // NSDefaultRunLoopMode will be used

列挙型の値が修飾されていない場合は、 NotSupportedException がスローされます。

ErrorDomainAttribute

エラー コードは列挙値としてバインドされます。 一般に、エラー ドメインがあり、どのドメインが適用されるか (存在する場合) を見つけることは常に簡単ではありません。

この属性を使用して、エラー ドメインを列挙型自体に関連付けることができます。

例:

[Native]
[ErrorDomain ("AVKitErrorDomain")]
public enum AVKitError : nint {
    None = 0,
    Unknown = -1000,
    PictureInPictureStartFailed = -1001
}

その後、拡張メソッド GetDomain を呼び出して、エラーのドメイン定数を取得できます。

FieldAttribute

これは、型内の定数に使用されるのと同じ [Field] 属性です。 列挙型内で使用して、特定の定数を持つ値をマップすることもできます。

値を null 使用して、定数が指定されている場合に返される列挙型の値を nullNSString 指定できます。

上記の例から:

var constant = NSRunLoopMode.NewInWatchOS3; // will be null in watchOS 2.x
Call (NSRunLoopModeExtensions.GetValue (constant)); // will return 1000

値が存在しない null 場合は、 ArgumentNullException がスローされます。

グローバル属性

グローバル属性は、 などの[LinkWithAttribute]属性修飾子を[assembly:]使用して適用されるか、 属性や [Since] 属性などの任意の場所で[Lion]使用できます。

LinkWithAttribute

これはアセンブリ レベルの属性であり、開発者は、ライブラリのコンシューマーがライブラリに渡されるgcc_flagsと追加の mtouch 引数を手動で構成しなくても、バインドされたライブラリを再利用するために必要なリンク フラグを指定できます。

構文:

// In properties
[Flags]
public enum LinkTarget {
    Simulator    = 1,
    ArmV6    = 2,
    ArmV7    = 4,
    Thumb    = 8,
}

[AttributeUsage(AttributeTargets.Assembly, AllowMultiple=true)]
public class LinkWithAttribute : Attribute {
    public LinkWithAttribute ();
    public LinkWithAttribute (string libraryName);
    public LinkWithAttribute (string libraryName, LinkTarget target);
    public LinkWithAttribute (string libraryName, LinkTarget target, string linkerFlags);
    public bool ForceLoad { get; set; }
    public string Frameworks { get; set; }
    public bool IsCxx { get; set;  }
    public string LibraryName { get; }
    public string LinkerFlags { get; set; }
    public LinkTarget LinkTarget { get; set; }
    public bool NeedsGccExceptionHandling { get; set; }
    public bool SmartLink { get; set; }
    public string WeakFrameworks { get; set; }
}

この属性はアセンブリ レベルで適用されます。たとえば、 CorePlot バインド で使用されるものは次のとおりです。

[assembly: LinkWith ("libCorePlot-CocoaTouch.a", LinkTarget.ArmV7 | LinkTarget.ArmV7s | LinkTarget.Simulator, Frameworks = "CoreGraphics QuartzCore", ForceLoad = true)]

属性を [LinkWith] 使用すると、指定した libraryName が結果のアセンブリに埋め込まれます。これにより、ユーザーは、アンマネージド依存関係と、Xamarin.iOS からライブラリを適切に使用するために必要なコマンド ライン フラグの両方を含む単一の DLL を出荷できます。

を指定 libraryNameしないことも可能です。この場合、 属性を使用して追加の LinkWith リンカー フラグのみを指定できます。

[assembly: LinkWith (LinkerFlags = "-lsqlite3")]

LinkWithAttribute コンストラクター

これらのコンストラクターを使用すると、リンクするライブラリを指定し、結果のアセンブリ、ライブラリでサポートされているサポート対象、およびライブラリとのリンクに必要なオプションのライブラリ フラグを指定できます。

LinkTarget引数は Xamarin.iOS によって推論され、設定する必要はありません。

例 :

// Specify additional linker:
[assembly: LinkWith (LinkerFlags = "-sqlite3")]

// Specify library name for the constructor:
[assembly: LinkWith ("libDemo.a");

// Specify library name, and link target for the constructor:
[assembly: LinkWith ("libDemo.a", LinkTarget.Thumb | LinkTarget.Simulator);

// Specify only the library name, link target and linker flags for the constructor:
[assembly: LinkWith ("libDemo.a", LinkTarget.Thumb | LinkTarget.Simulator, SmartLink = true, ForceLoad = true, IsCxx = true);

LinkWithAttribute.ForceLoad

プロパティは ForceLoad 、ネイティブ ライブラリのリンクにリンク フラグを -force_load 使用するかどうかを決定するために使用されます。 現時点では、これは常に true である必要があります。

LinkWithAttribute.Frameworks

バインドされているライブラリに(および UIKit以外Foundationの) フレームワークに対するハード要件がある場合は、 プロパティをFrameworks、必要なプラットフォーム フレームワークのスペース区切りリストを含む文字列に設定する必要があります。 たとえば、 と を必要CoreGraphicsとするライブラリをバインドする場合は、 プロパティを Frameworks"CoreGraphics CoreText"設定CoreTextします。

LinkWithAttribute.IsCxx

既定の C コンパイラ (C コンパイラ) ではなく C++ コンパイラを使用して結果の実行可能ファイルをコンパイルする必要がある場合は、このプロパティを true に設定します。 バインドするライブラリが C++ で記述されている場合は、これを使用します。

LinkWithAttribute.LibraryName

バンドルするアンマネージド ライブラリの名前。 これは拡張子 ".a" のファイルであり、複数のプラットフォーム (シミュレーターの場合は ARM や x86 など) のオブジェクト コードを含めることができます。

以前のバージョンの Xamarin.iOS では、 プロパティを LinkTarget チェックしてライブラリでサポートされているプラットフォームを確認しましたが、これが自動検出され LinkTarget 、プロパティは無視されます。

LinkWithAttribute.LinkerFlags

この文字列を LinkerFlags 使用すると、ネイティブ ライブラリをアプリケーションにリンクするときに必要な追加のリンカー フラグをバインド作成者が指定できます。

たとえば、ネイティブ ライブラリに libxml2 と zlib が必要な場合は、文字列を LinkerFlags"-lxml2 -lz"設定します。

LinkWithAttribute.LinkTarget

以前のバージョンの Xamarin.iOS では、 プロパティを LinkTarget チェックしてライブラリでサポートされているプラットフォームを確認しましたが、これが自動検出され LinkTarget 、プロパティは無視されます。

LinkWithAttribute.NeedsGccExceptionHandling

リンクするライブラリに GCC 例外処理ライブラリが必要な場合は、このプロパティを true に設定します (gcc_eh)

SmartLink Xamarin.iOS が必要かどうかをForceLoad判断できるようにするには、 プロパティを true に設定する必要があります。

LinkWithAttribute.WeakFrameworks

プロパティは WeakFrameworks プロパティと Frameworks 同じように動作しますが、リンク時 -weak_framework に指定子が一覧表示されているフレームワークごとに gcc に渡される点が除きます。

WeakFrameworks を使用すると、ライブラリとアプリケーションがプラットフォーム フレームワークと弱くリンクできるため、使用可能な場合は必要に応じて使用できますが、ライブラリにハード依存関係を持たないようにすることができます。これは、ライブラリが新しいバージョンの iOS に追加機能を追加する場合に役立ちます。 弱いリンクの詳細については、弱いリンク に関する Apple のドキュメントを参照してください。

弱いリンクの適切な候補はFrameworks、アカウント、CoreBluetoothCoreImageGLKitNewsstandKitおよび Twitter のようになります。iOS 5 でのみ使用できるためです。

SinceAttribute (iOS) と LionAttribute (macOS)

属性を [Since] 使用して、API に特定の時点で導入されたものとしてフラグを設定します。 属性は、基になるクラス、メソッド、またはプロパティが使用できない場合にランタイムの問題を引き起こす可能性がある型とメソッドにフラグを設定するためにのみ使用する必要があります。

構文:

public SinceAttribute : Attribute {
     public SinceAttribute (byte major, byte minor);
     public byte Major, Minor;
}

一般に、列挙型、制約、または新しい構造体には適用しないでください。古いバージョンのオペレーティング システムを持つデバイスで実行された場合、ランタイム エラーは発生しないためです。

型に適用される例:

// Type introduced with iOS 4.2
[Since (4,2)]
[BaseType (typeof (UIPrintFormatter))]
interface UIViewPrintFormatter {
    [Export ("view")]
    UIView View { get; }
}

新しいメンバーに適用される例:

[BaseType (typeof (UIViewController))]
public interface UITableViewController {
    [Export ("tableView", ArgumentSemantic.Retain)]
    UITableView TableView { get; set; }

    [Since (3,2)]
    [Export ("clearsSelectionOnViewWillAppear")]
    bool ClearsSelectionOnViewWillAppear { get; set; }

属性は [Lion] 同じ方法で適用されますが、Lion で導入された型にも適用されます。 iOS で使用されるより具体的なバージョン番号と比較して使用 [Lion] する理由は、iOS が頻繁に改訂されるのに対し、OS X のメジャー リリースはまれに発生し、バージョン番号よりもコード名でオペレーティング システムを覚える方が簡単であるためです。

AdviceAttribute

この属性を使用して、開発者が使用する方が便利な他の API に関するヒントを開発者に提供します。 たとえば、厳密に型指定されたバージョンの API を指定する場合は、弱く型指定された属性でこの属性を使用して、開発者をより適切な API に誘導できます。

この属性の情報はドキュメントに示されており、改善方法に関するユーザーの提案を提供するためにツールを開発できます

RequiresSuperAttribute

これは、 属性の [Advice] 特殊化されたサブクラスであり、メソッドをオーバーライドするには、基本 (オーバーライドされた) メソッドの呼び出しが 必要 であることを開発者に示唆するために使用できます。

これは に対応します。 clang__attribute__((objc_requires_super))

ZeroCopyStringsAttribute

Xamarin.iOS 5.4 以降でのみ使用できます。

この属性は、この特定のライブラリのバインド (で適用されている場合) または型で [assembly:]高速ゼロ コピー文字列マーシャリングを使用するようにジェネレーターに指示します。 この属性は、コマンド ライン オプション --zero-copy をジェネレーターに渡すことと同じです。

文字列にゼロ コピーを使用する場合、ジェネレーターでは、新しいNSStringオブジェクトの作成が発生せず、C# 文字列から文字列へのデータのコピーを回避することなく、使用するObjective-C文字列と同じ C# 文字列を効果的にObjective-C使用します。 ゼロ コピー文字列を使用する唯一の欠点は、ラップする文字列プロパティに 属性が設定されているか、または copy としてretainフラグが設定されていることを確認する[DisableZeroCopy]必要がある点です。 これは、ゼロ コピー文字列のハンドルがスタックに割り当てられ、関数が戻ると無効であるために必要です。

例:

[ZeroCopyStrings]
[BaseType (typeof (NSObject))]
interface MyBinding {
    [Export ("name")]
    string Name { get; set; }

    [Export ("domain"), NullAllowed]
    string Domain { get; set; }

    [DisablZeroCopy]
    [Export ("someRetainedNSString")]
    string RetainedProperty { get; set; }
}

また、アセンブリ レベルで 属性を適用することもできます。また、アセンブリのすべての型に適用されます。

[assembly:ZeroCopyStrings]

厳密に型指定されたディクショナリ

Xamarin.iOS 8.0 では、 をラップ NSDictionariesする厳密に型指定されたクラスを簡単に作成するためのサポートが導入されました。

DictionaryContainer データ型を手動 API と共に使用することは常に可能ですが、これを行う方がずっと簡単になりました。 詳細については、「 厳密な型の表示」を参照してください。

StrongDictionary

この属性がインターフェイスに適用されると、ジェネレーターは DictionaryContainer から派生したインターフェイスと同じ名前のクラスを生成し、インターフェイスで定義されている各プロパティをディクショナリの厳密に型指定されたゲッターとセッターに変換します。

これにより、既存 NSDictionary の からインスタンス化できるクラス、または新しく作成されたクラスが自動的に生成されます。

この属性は、1 つのパラメーターを受け取ります。これは、ディクショナリ上の要素にアクセスするために使用されるキーを含むクラスの名前です。 既定では、 属性を持つインターフェイスの各プロパティは、指定された型のメンバーを検索し、サフィックス "Key" を持つ名前を検索します。

次に例を示します。

[StrongDictionary ("MyOptionKeys")]
interface MyOption {
    string Name { get; set; }
    nint    Age  { get; set; }
}

[Static]
interface MyOptionKeys {
    // In Objective-C this is "NSString *MYOptionNameKey;"
    [Field ("MYOptionNameKey")]
    NSString NameKey { get; }

    // In Objective-C this is "NSString *MYOptionAgeKey;"
    [Field ("MYOptionAgeKey")]
    NSString AgeKey { get; }
}

上記の場合、 MyOption クラスは の文字列プロパティ Name を生成し、 をディクショナリのキーとして使用 MyOptionKeys.NameKey して文字列を取得します。 では、 をディクショナリのキーとして使用 MyOptionKeys.AgeKey して、int を含む を NSNumber 取得します。

別のキーを使用する場合は、 プロパティで export 属性を使用できます。次に例を示します。

[StrongDictionary ("MyColoringKeys")]
interface MyColoringOptions {
    [Export ("TheName")]  // Override the default which would be NameKey
    string Name { get; set; }

    [Export ("TheAge")] // Override the default which would be AgeKey
    nint    Age  { get; set; }
}

[Static]
interface MyColoringKeys {
    // In Objective-C this is "NSString *MYColoringNameKey"
    [Field ("MYColoringNameKey")]
    NSString TheName { get; }

    // In Objective-C this is "NSString *MYColoringAgeKey"
    [Field ("MYColoringAgeKey")]
    NSString TheAge { get; }
}

厳密なディクショナリ型

定義では、次のデータ型が StrongDictionary サポートされています。

C# インターフェイスの種類 NSDictionary ストレージの種類
bool Boolean に格納されます。 NSNumber
列挙値 に格納されている整数 NSNumber
int に格納されている 32 ビット整数 NSNumber
uint に格納されている 32 ビット符号なし整数 NSNumber
nint NSInteger に格納されます。 NSNumber
nuint NSUInteger に格納されます。 NSNumber
long に格納されている 64 ビット整数 NSNumber
float として格納される 32 ビット整数 NSNumber
double として格納される 64 ビット整数 NSNumber
NSObject サブクラスと サブクラス NSObject
NSDictionary NSDictionary
string NSString
NSString NSString
の C# ArrayNSObject NSArray
列挙の C# Array NSArray 値を NSNumber 含む