Aracılığıyla paylaş


Bağlama türleri başvuru kılavuzu

Bu belgede, bağlamayı ve oluşturulan kodu yönlendirmek üzere API sözleşme dosyalarınıza ek açıklama eklemek için kullanabileceğiniz özniteliklerin listesi açıklanmaktadır

Xamarin.iOS ve Xamarin.Mac API sözleşmeleri çoğunlukla C# dilinde kodun C# olarak nasıl ortaya çıkarılacağını Objective-C tanımlayan arabirim tanımları olarak yazılır. İşlem, arabirim bildirimlerinin bir karışımını ve API sözleşmesinin gerektirebileceği bazı temel tür tanımlarını içerir. Bağlama türlerine giriş için yardımcı kılavuzumuz Olan Bağlama Objective-C Kitaplıkları'na bakın.

Tür tanımları

Söz dizimi:

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

Anlaşma tanımınızda özniteliği olan [BaseType] her arabirim, oluşturulan nesne için temel türü bildirir. Yukarıdaki bildirimde adlı MyTypebir türe bağlanan bir MyTypeObjective-C sınıf C# türü oluşturulur.

Arabirim devralma söz dizimini kullanarak tür adından sonra herhangi bir tür belirtirseniz (yukarıdaki Protocol1 örnekte ve Protocol2) bu arabirimlerin içeriği için MyTypesözleşmenin bir parçası olmuş gibi çizilir. Xamarin.iOS'un bir türün bir protokolü benimsediği yüzeylerinin yolu, protokolde bildirilen tüm yöntemlerin ve özelliklerin türün kendisine çizilmesidir.

Aşağıda bildiriminin Objective-CUITextField bir Xamarin.iOS sözleşmesinde nasıl tanımlandığı gösterilmektedir:

@interface UITextField : UIControl <UITextInput> {

}

C# API sözleşmesi olarak şöyle yazılır:

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

Arabirime başka öznitelikler uygulayarak ve özniteliğini yapılandırarak kod oluşturmanın [BaseType] diğer birçok yönünü denetleyebilirsiniz.

Olay oluşturma

Xamarin.iOS ve Xamarin.Mac API tasarımının bir özelliği, temsilci sınıflarını C# olayları ve geri çağırmalar olarak eşlememizdir Objective-C . Kullanıcılar, çalışma zamanının çağıracağı çeşitli yöntemleri Objective-C uygulayan bir sınıfın Objective-C örneği gibi Delegate özelliklere atayarak veya C#stili olayları ve özellikleri seçerek programlama desenini benimsemek isteyip istemediklerini örnek temelinde seçebilir.

Modelin nasıl kullanılacağına Objective-C ilişkin bir örnek görelim:

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 ();
    }
}

Yukarıdaki örnekte, iki yöntemin üzerine yazmayı seçtiğimizi, birinin kaydırma olayının gerçekleştiğini belirten bir bildirim ve ikincisi ise en üste kaydırılıp kaydırılmayacağını belirten scrollView boole değeri döndürmesi gereken bir geri çağırma olduğunu görebilirsiniz.

C# modeli, kitaplığınızın kullanıcısının C# olay söz dizimini veya özellik söz dizimini kullanarak değerleri döndürmesi beklenen geri çağırmaları bağlamak için bildirimleri dinlemesine olanak tanır.

Aynı özelliğin C# kodu lambda'ları kullanmaya benzer:

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 ();
}

Olaylar değer döndürmediğinden (geçersiz dönüş türüne sahiptir) birden çok kopya bağlayabilirsiniz. ShouldScrollToTop bir olay değil, bunun yerine bu imzaya sahip türüne UIScrollViewCondition sahip bir özelliktir:

public delegate bool UIScrollViewCondition (UIScrollView scrollView);

Bir değer döndürür bool , bu durumda lambda söz dizimi işlevinden MakeDecision yalnızca değeri döndürmemize olanak tanır.

Bağlama oluşturucu, gibi UIScrollViewUIScrollViewDelegate bir sınıfı ile bağlayan olaylar ve özellikler oluşturmayı destekler (bunlara Model sınıfı deyin), bu, tanımınıza [BaseType] ve Delegates parametreleriyle Events ek açıklama eklenerek yapılır (aşağıda açıklanmıştır). öğesine bu parametrelerle ek açıklama [BaseType] eklemeye ek olarak, oluşturucuya birkaç bileşen daha hakkında bilgi vermek gerekir.

Birden fazla parametre alan olaylar için (kuralda Objective-C , temsilci sınıfındaki ilk parametrenin gönderen nesnesinin örneği olmasıdır) oluşturulan EventArgs sınıfın olmasını istediğiniz adı sağlamanız gerekir. Bu, Model sınıfınızdaki yöntem bildirimindeki özniteliğiyle [EventArgs] yapılır. Örneğin:

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

Yukarıdaki bildirim, ve parametrelerinin UIImage her ikisinden EventArgs de türetilen ve NSDictionarypaketleyen bir UIImagePickerImagePickedEventArgs sınıf oluşturur. Oluşturucu şunu üretir:

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

Ardından sınıfında aşağıdakileri UIImagePickerController kullanıma sunar:

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

Değer döndüren model yöntemleri farklı şekilde bağlanır. Bunlar hem oluşturulan C# temsilcisi için bir ad (yöntemin imzası) hem de kullanıcının bir uygulama sağlamaması durumunda döndürülecek bir varsayılan değer gerektirir. Örneğin, ShouldScrollToTop tanımı şudur:

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

Yukarıdaki, yukarıda gösterilen imzaya sahip bir UIScrollViewCondition temsilci oluşturur ve kullanıcı bir uygulama sağlamazsa dönüş değeri true olur.

Özniteliğine [DefaultValue] ek olarak, oluşturucuyu [DefaultValueFromArgument] çağrıda belirtilen parametrenin değerini döndürmeye yönlendiren özniteliğini veya [NoDefaultValue] oluşturucuya varsayılan değer olmadığını belirten parametreyi de kullanabilirsiniz.

BaseTypeAttribute

Söz dizimi:

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

Bu türün Name dünyada bağlanacağı adı denetlemek için Objective-C özelliğini kullanırsınız. Bu genellikle C# türüne .NET Framework Tasarım Yönergeleri ile uyumlu, ancak bu kurala uymayan bir adla eşlenen bir ad Objective-C vermek için kullanılır.

Örneğin, .NET Framework Tasarım Yönergelerinde "URL" yerine "Url" kullanıldığı içinNSUrlConnection, aşağıdaki örnekte türü ile eşlenir:Objective-CNSURLConnection

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

Belirtilen ad, bağlamada oluşturulan [Register] özniteliğin değeri olarak kullanılır. Belirtilmezse Name , türün kısa adı, oluşturulan çıktıdaki özniteliğin [Register] değeri olarak kullanılır.

BaseType.Events ve BaseType.Delegates

Bu özellikler, oluşturulan sınıflarda C#stilinde olayların oluşturulmasını yönlendirmek için kullanılır. Belirli bir sınıfı temsilci sınıfına Objective-C bağlamak için kullanılır. Bir sınıfın bildirim ve olay göndermek için temsilci sınıfı kullandığı birçok durumla karşılaşırsınız. Örneğin, bir BarcodeScanner eşlikçi BardodeScannerDelegate sınıfına sahip olur. sınıfı BarcodeScanner genellikle bir örneğini BarcodeScannerDelegate atayacağınız bir Delegate özelliğe sahip olur, ancak bu işe yarar, kullanıcılarınıza C#benzeri bir stil olay arabirimi göstermek isteyebilirsiniz ve bu durumlarda özniteliğinin Events[BaseType] ve Delegates özelliklerini kullanabilirsiniz.

Bu özellikler her zaman birlikte ayarlanır ve aynı sayıda öğeye sahip olmalı ve eşitlenmiş durumda tutulmalıdır. Dizi, Delegates kaydırmak istediğiniz zayıf türdeki her temsilci için bir dize içerir ve Events dizi, kendisiyle ilişkilendirmek istediğiniz her tür için bir tür içerir.

[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

Bu sınıfın yeni örnekleri oluşturulduğunda bu özniteliği uygularsanız, tarafından başvurulan KeepRefUntil yöntem çağrılana kadar bu nesnenin örneği çevresinde tutulur. Bu, kullanıcınızın kodunuzu kullanmak üzere bir nesneye başvuru tutmasını istemediğinizde API'lerinizin kullanılabilirliğini geliştirmek için yararlıdır. Bu özelliğin değeri sınıfındaki Delegate bir yöntemin adıdır, bu nedenle bunu ve Delegates özellikleriyle Events birlikte kullanmanız gerekir.

Aşağıdaki örnekte bunun Xamarin.iOS'ta nasıl kullanıldığı UIActionSheet gösterilmektedir:

[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

Bu öznitelik arabirim tanımına uygulandığında, varsayılan (oluşturulan) oluşturucuda seçiciye init eşlenen bir [DesignatedInitializer] öznitelik oluşturur.

DisableDefaultCtorAttribute

Bu öznitelik arabirim tanımına uygulandığında, oluşturucunun varsayılan oluşturucuyu üretmesini engeller.

Nesnenin sınıftaki diğer oluşturuculardan biriyle başlatılması gerektiğinde bu özniteliği kullanın.

PrivateDefaultCtorAttribute

Bu öznitelik arabirim tanımına uygulandığında, varsayılan oluşturucuyu özel olarak işaretler. Bu, uzantı dosyanızdan bu sınıfın nesnesinin örneğini yine de oluşturabileceğiniz ancak sınıfınızın kullanıcıları tarafından erişilmeyeceği anlamına gelir.

Categoryattribute

Kategorileri bağlamak Objective-C ve bunları C# uzantısı yöntemleri olarak kullanıma açmak için bu özniteliği bir tür tanımında kullanarak işlevin kullanıma sunma şeklini Objective-C yansıtın.

Kategoriler, bir Objective-C sınıfta kullanılabilen yöntem ve özellik kümesini genişletmek için kullanılan bir mekanizmadır. Uygulamada, temel sınıfın işlevselliğini (örneğin NSObject, içinde belirli bir çerçeve bağlandığında) genişletmek için kullanılırlar (örneğin UIKit), yöntemlerini kullanılabilir hale getirir, ancak yalnızca yeni çerçeve bağlıysa. Bazı diğer durumlarda, bir sınıftaki özellikleri işlevlere göre düzenlemek için kullanılırlar. C# uzantı yöntemlerine benzerler.

içinde bir kategori şöyle görünür Objective-C:

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

Yukarıdaki örnek, yöntemini makeBackgroundRedkullanarak örneklerini UIView genişleten bir kitaplıkta bulunur.

Bunları bağlamak için bir arabirim tanımında özniteliğini [Category] kullanabilirsiniz. özniteliği kullanılırken [Category] , özniteliğin [BaseType] anlamı genişletilmesi gereken temel sınıfı belirtmek için kullanılmaktan genişletilen türe dönüşür.

Aşağıda uzantıların UIView nasıl bağlı olduğu ve C# uzantı yöntemlerine nasıl dönüştürülmesi gösterilmektedir:

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

Yukarıdaki, uzantı yöntemini içeren MakeBackgroundRed bir MyUIViewExtension sınıf oluşturur. Bu, artık herhangi bir UIView alt sınıfta çağrı MakeBackgroundRed yapabileceğiniz ve size ile aynı Objective-Cişlevselliği sağlayabileceğiniz anlamına gelir.

Bazı durumlarda, aşağıdaki örnekte olduğu gibi kategorilerin içinde statik üyeler bulacaksınız:

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

Bu, yanlış bir Kategori C# arabirimi tanımına yol açar:

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

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

Örneğine ihtiyacınız olan ancak ObjC statik uzantısını bağladığınız uzantıyı FooObject kullanmak BoolMethod için bu yanlıştır; bu, C# uzantı yöntemlerinin nasıl uygulandığı gerçeğinden kaynaklanan bir yan etkidir.

Yukarıdaki tanımları kullanmanın tek yolu aşağıdaki çirkin koddur:

(null as FooObject).BoolMethod (range);

Bunu önlemek için öneri, tanımı arabirim tanımının BoolMethodFooObject kendi içinde satır içine almaktır; bu, bu uzantıyı amaçlandığı FooObject.BoolMethod (range)gibi çağırmanıza olanak sağlar.

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

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

Bir tanımın içinde [Category] bir üye bulduğumuzda [Static] bir uyarı (BI1117) yapacağız. Tanımlarınızda [Category] gerçekten üye olmasını [Static] istiyorsanız, kullanarak veya ile [Internal]üyenizi [Category] veya arabirim tanımınızı süsleyerek uyarıyı [Category (allowStaticMembers: true)] susturabilirsiniz.

StaticAttribute

Bu öznitelik bir sınıfa uygulandığında yalnızca öğesinden NSObjecttüretilmeyen bir statik sınıf oluşturur, bu nedenle [BaseType] özniteliği yoksayılır. Statik sınıflar, kullanıma açmak istediğiniz C ortak değişkenlerini barındırmak için kullanılır.

Örneğin:

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

Aşağıdaki API ile bir C# sınıfı oluşturur:

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

Protokol/Model tanımları

Modeller genellikle protokol uygulaması tarafından kullanılır. Çalışma zamanının yalnızca aslında üzerine yazılmış yöntemlerle Objective-C kaydolması açısından farklılık gösterir. Aksi takdirde, yöntemi kaydedilmez.

Bu genel olarak, ile ModelAttributebayrak eklenmiş bir sınıfı alt sınıfa aldığınızda temel yöntemi çağırmamanız gerektiği anlamına gelir. Bu yöntemi çağırmak şu özel durumu oluşturur: Foundation.You_Should_Not_Call_base_In_This_Method. Geçersiz kıldığınız tüm yöntemler için alt sınıfınızdaki davranışın tamamını uygulamanız gerekir.

AbstractAttribute

Varsayılan olarak, bir protokolün parçası olan üyeler zorunlu değildir. Bu, kullanıcıların yalnızca C# sınıfından Model türeterek ve yalnızca önem verdikleri yöntemleri geçersiz kılarak nesnenin bir alt sınıfını oluşturmasına olanak tanır. Bazen sözleşme, Objective-C kullanıcının bu yöntem için bir uygulama sağlamasını gerektirir (bunlar içinde Objective-Cyönergesiyle @required işaretlenir). Bu gibi durumlarda, bu yöntemleri özniteliğiyle bayrakla [Abstract] işaretlemeniz gerekir.

[Abstract] özniteliği yöntemlere veya özelliklere uygulanabilir ve oluşturucunun oluşturulan üyeyi soyut, sınıfı ise soyut sınıf olarak işaretlemesine neden olur.

Xamarin.iOS'tan aşağıdakiler alınır:

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

Defaultvalueattribute

Kullanıcı Model nesnesinde bu yöntem için bir yöntem sağlamazsa model yöntemi tarafından döndürülecek varsayılan değeri belirtir

Söz dizimi:

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

Örneğin, bir Camera sınıfın aşağıdaki sanal temsilci sınıfında, sınıfında özellik Camera olarak kullanıma sunulacak bir sağlarızShouldUploadToServer. Sınıfın Camera kullanıcısı değeri açıkça true veya false yanıt verebilen bir lambda olarak ayarlamazsa, bu durumda varsayılan değer döndüren false olur ve özniteliğinde DefaultValue belirttiğimiz değer:

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

Kullanıcı sanal sınıfta bir işleyici ayarlarsa, bu değer yoksayılır:

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

Ayrıca bkz: [NoDefaultValue], [DefaultValueFromArgument].

DefaultValueFromArgumentAttribute

Söz dizimi:

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

Model sınıfında bir değer döndüren bir yöntemde sağlandığında bu öznitelik, kullanıcı kendi yöntemini veya lambda'sını sağlamadıysa oluşturucuya belirtilen parametrenin değerini döndürmesini bildirir.

Örnek:

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

Yukarıdaki örnekte, sınıfın NSAnimation kullanıcısı C# olaylarından/özelliklerinden herhangi birini kullanmayı seçtiyse ve bir yöntem veya lambda olarak ayarlanmadıysa NSAnimation.ComputeAnimationCurve , dönüş değeri ilerleme parametresinde geçirilen değer olacaktır.

Ayrıca bkz: [NoDefaultValue], [DefaultValue]

IgnoredInDelegateAttribute

Bazen model sınıfından bir olayı veya temsilci özelliğini konak sınıfına sunmamak mantıklıdır, bu nedenle bu özniteliğin eklenmesi oluşturucuya kendisiyle dekore edilmiş herhangi bir yöntemin oluşturulmasını önlemesini bildirir.

[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

Bu öznitelik, kullanılacak temsilci imzasının adını ayarlamak için değerler döndüren Model yöntemlerinde kullanılır.

Örnek:

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

Yukarıdaki tanım ile oluşturucu aşağıdaki genel bildirimi oluşturur:

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

DelegateApiNameAttribute

Bu öznitelik, oluşturucunun konak sınıfında oluşturulan özelliğin adını değiştirmesine izin vermek için kullanılır. Bazen, FooDelegate sınıf yönteminin adı Delegate sınıfı için anlamlı olduğunda, ancak konak sınıfında özellik olarak tek göründüğünde yararlıdır.

Ayrıca, fooDelegate sınıfında olduğu gibi adlandırılmalarını sağlamak için anlamlı olan iki veya daha fazla aşırı yükleme yönteminiz olduğunda ancak bunları konak sınıfında daha iyi bir adla kullanıma açmak istediğinizde bu gerçekten yararlıdır (ve gereklidir).

Örnek:

[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);
}

Yukarıdaki tanım ile oluşturucu konak sınıfında aşağıdaki genel bildirimi oluşturur:

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

EventArgsAttribute

Birden fazla parametre alan olaylar için (kuralda Objective-C , temsilci sınıfındaki ilk parametrenin gönderen nesnesinin örneği olmasıdır) oluşturulan EventArgs sınıfının olmasını istediğiniz adı sağlamanız gerekir. Bu, sınıfınızdaki Model yöntem bildirimindeki özniteliğiyle [EventArgs] yapılır.

Örneğin:

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

Yukarıdaki bildirim, EventArgs'ten türetilen ve hem hem de parametrelerini UIImageNSDictionarypaketleyen bir UIImagePickerImagePickedEventArgs sınıf oluşturur. Oluşturucu şunu üretir:

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

Ardından sınıfında aşağıdakileri UIImagePickerController kullanıma sunar:

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

EventNameAttribute

Bu öznitelik, oluşturucunun sınıfında oluşturulan bir olayın veya özelliğin adını değiştirmesine izin vermek için kullanılır. Bazen Model sınıfı yönteminin adı model sınıfı için anlamlı olduğunda, ancak kaynak sınıfta bir olay veya özellik olarak garip göründüğünde yararlıdır.

Örneğin, öğesinin UIWebView aşağıdaki bitini UIWebViewDelegatekullanır:

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

Yukarıdaki, içinde yöntemi UIWebViewDelegateolarak, ancak LoadFinished içinde UIWebViewbağlanacak olay olarak kullanıma sunarLoadingFinished:

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

ModelAttribute

özniteliğini [Model] sözleşme API'nizdeki bir tür tanımına uyguladığınızda, çalışma zamanı yalnızca kullanıcı sınıftaki bir yöntemin üzerine yazdıysa sınıftaki yöntemlere çağrıları ortaya çıkarabilecek özel kod oluşturur. Bu öznitelik genellikle bir Objective-C temsilci sınıfını sarmalayan tüm API'lere uygulanır.

Çalışma zamanı, ilgili protokolün adıyla eşleşen bir Objective-C sınıf da oluşturur.

Sınıfın adını Objective-C iki şekilde özelleştirmek mümkündür:

  1. Ayar AutoGeneratedName = true:

    [Model (AutoGeneratedName = true)]
    

    Bu, çalışma zamanının tür için benzersiz bir ad oluşturmasını Objective-C sağlar. Ad şu anda derleme adını ve modelin türünün tam adını temel alır (bu gelecekte değişebilir).

  2. Adı açıkça belirtme:

    [Model (Name = "CustomName")]
    

kullanılması AutoGeneratedName = trueönerilir. .NET'te ad her zaman oluşturulur (yukarıda 2. olarak açıkça belirtilmedikçe) ve AutoGeneratedName özelliği artık mevcut değildir.

NoDefaultValueAttribute

Modeldeki yönteminin varsayılan bir dönüş değeri sağlamadığını belirtir.

Bu, belirtilen seçicinin Objective-C bu sınıfta uygulanıp uygulanmadığını belirlemek için çalışma zamanı isteğine yanıt vererek falseObjective-C çalışma zamanıyla birlikte çalışır.

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

Ayrıca bkz: [DefaultValue], [DefaultValueFromArgument]

Protokoller

Protokol Objective-C kavramı gerçekten C# dilinde mevcut değildir. Protokoller C# arabirimlerine benzer, ancak bir protokolde bildirilen yöntemlerin ve özelliklerin tümünün bunu benimseyen sınıf tarafından uygulanması gerekmediğinden farklıdır. Bunun yerine bazı yöntemler ve özellikler isteğe bağlıdır.

Bazı protokoller genellikle Model sınıfları olarak kullanılır, bunlar özniteliği kullanılarak [Model] bağlanmalıdır.

[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'dan itibaren yeni ve geliştirilmiş bir protokol bağlama işlevi birleştirildi. özniteliğini [Protocol] içeren herhangi bir tanım, protokolleri kullanma yönteminizi büyük ölçüde geliştiren üç destekleyici sınıf oluşturur:

// 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);
    }
}

Sınıf uygulaması, tek tek yöntemlerini geçersiz kılabileceğiniz ve tam tür güvenliği alabileceğiniz eksiksiz bir soyut sınıf sağlar. Ancak C# birden çok devralmayı desteklemediğinden, farklı bir temel sınıf gerektirebileceğiniz ancak yine de bir arabirim uygulamak isteyebileceğiniz senaryolar vardır.

Oluşturulan arabirim tanımı burada devreye girer. Protokolden tüm gerekli yöntemleri içeren bir arabirimdir. Bu, protokolünüzü uygulamak isteyen geliştiricilerin yalnızca arabirimi uygulamasına olanak tanır. Çalışma zamanı türü otomatik olarak protokolü benimseyerek kaydeder.

Arabirimin yalnızca gerekli yöntemleri listelediğini ve isteğe bağlı yöntemleri kullanıma sunar. Bu, protokolü benimseyen sınıfların gerekli yöntemler için tam tür denetimine sahip olacağı, ancak isteğe bağlı protokol yöntemleri için zayıf yazmaya (öznitelikleri el ile dışarı aktarma ve imzayla eşleştirme kullanarak) başvurması gerektiği anlamına gelir.

Bağlama aracı, protokol kullanan bir API'yi kullanmayı kolaylaştırmak için isteğe bağlı tüm yöntemleri kullanıma sunan bir uzantı yöntemi sınıfı da oluşturur. Bu, BIR API kullandığınız sürece protokolleri tüm yöntemlere sahip olarak değerlendirebilmeniz anlamına gelir.

API'nizde protokol tanımlarını kullanmak istiyorsanız API tanımınıza boş iskelet arabirimleri yazmanız gerekir. MyProtocol'unu bir API'de kullanmak istiyorsanız, bunu yapmanız gerekir:

[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 ();
}

Yukarıdakiler gereklidir çünkü bağlama zamanında IMyProtocol mevcut olmaz, bu nedenle boş bir arabirim sağlamanız gerekir.

Protokol tarafından oluşturulan arabirimleri benimseme

Protokoller için oluşturulan arabirimlerden birini her uyguladığınızda, aşağıdaki gibi:

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

Gerekli arabirim yöntemlerinin uygulaması uygun adla dışarı aktarılır, bu nedenle şuna eşdeğerdir:

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

Bu, tüm gerekli protokol üyeleri için çalışır, ancak dikkat edilmesi gereken isteğe bağlı seçiciler içeren özel bir durum vardır.

İsteğe bağlı protokol üyeleri, temel sınıf kullanılırken aynı şekilde değerlendirilir:

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

ancak protokol arabirimini kullanırken [Dışarı Aktar] öğesini eklemek gerekir. IDE, geçersiz kılma ile başlayarak eklediğinizde otomatik tamamlama yoluyla ekler.

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

Çalışma zamanında ikisi arasında küçük bir davranış farkı vardır:

  • Temel sınıfın kullanıcıları (örnekte NSUrlSessionDownloadDelegate), tüm gerekli ve isteğe bağlı seçicileri sağlayarak makul varsayılan değerler döndürür.
  • Arabirimin kullanıcıları (örnekte INSUrlSessionDownloadDelegate) yalnızca sağlanan seçicileri tam olarak yanıtlar.

Bazı nadir sınıflar burada farklı davranabilir. Hemen hemen her durumda, ancak her ikisini de kullanmak güvenlidir.

Protokol inlining

Bir protokolü benimsediği bildirilen mevcut Objective-C türleri bağlarken, protokolü doğrudan satır içi olarak satır içi yapmak istersiniz. Bunu yapmak için, protokolünüzü yalnızca herhangi [BaseType] bir özniteliği olmayan bir arabirim olarak bildirin ve protokolü arabiriminizin temel arabirimleri listesinde listeleyin.

Örnek:

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

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

Üye tanımları

Bu bölümdeki öznitelikler bir türün tek tek üyelerine uygulanır: özellikler ve yöntem bildirimleri.

AlignAttribute

Özellik dönüş türleri için hizalama değerini belirtmek için kullanılır. Bazı özellikler, belirli sınırlarda hizalanması gereken adreslerin işaretçilerini alır (Xamarin.iOS'ta bu, örneğin 16 bayt hizalanmış olması gereken bazı GLKBaseEffect özelliklerde gerçekleşir). Bu özelliği kullanarak alıcıyı süsleyebilir ve hizalama değerini kullanabilirsiniz. Bu genellikle API'lerle tümleştirildiğinde ve OpenTK.Matrix4 türleriyle Objective-COpenTK.Vector4 birlikte kullanılır.

Örnek:

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

GörünümAttribute

[Appearance] Özniteliği, Görünüm yöneticisinin tanıtıldığı iOS 5 ile sınırlıdır.

özniteliği, [Appearance] çerçeveye katılan UIAppearance herhangi bir yönteme veya özelliğe uygulanabilir. Bu öznitelik bir sınıftaki bir yönteme veya özelliğe uygulandığında, bağlama oluşturucuyu bu sınıfın tüm örneklerini veya belirli ölçütlerle eşleşen örnekleri biçimlendirmek için kullanılan kesin olarak belirlenmiş bir görünüm sınıfı oluşturmaya yönlendirir.

Örnek:

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

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

Yukarıdakiler UIToolbar'da aşağıdaki kodu oluşturur:

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)

yöntem çağırmasını [AutoReleaseAttribute] içindeki NSAutoReleasePoolyöntemine sarmamak için on yöntemlerini ve özelliklerini kullanın.

içinde Objective-C , varsayılan NSAutoReleasePoolöğesine eklenen değerleri döndüren bazı yöntemler vardır. Varsayılan olarak, bunlar iş parçacığınıza gider, ancak Xamarin.iOS yönetilen nesne yaşadığı sürece nesnelerinize başvuruda bulunduğundan, içinde yalnızca iş parçacığınız denetimi bir sonraki iş parçacığına NSAutoReleasePooldöndürene kadar boşaltılacak ek bir başvuru NSAutoReleasePool tutmak istemeyebilirsiniz veya ana döngüye geri dönersiniz.

Bu öznitelik, örneğin varsayılan NSAutoReleasePoolöğesine eklenmiş nesneleri döndüren ağır özelliklere (örneğinUIImage.FromFile) uygulanır. Bu öznitelik olmadan, iş parçacığınız denetimi ana döngüye döndürmediği sürece görüntüler korunur. Yazışmanız her zaman canlı ve iş için bekleyen bir tür arka plan indiricisiydi, görüntüler asla yayınlanmazdı.

ForcedTypeAttribute

[ForcedTypeAttribute], döndürülen yönetilmeyen nesne bağlama tanımında açıklanan türle eşleşmese bile yönetilen tür oluşturmayı zorlamak için kullanılır.

Bu, bir üst bilgide açıklanan tür yerel yöntemin döndürülen türüyle eşleşmediğinde yararlıdır, örneğin Objective-C aşağıdaki tanımı alın:NSURLSession

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

Bir örnek döndüreceğini NSURLSessionDownloadTask açıkça belirtir, ancak yine de bir üst sınıf olan ve dolayısıyla dönüştürülemez NSURLSessionDownloadTaskolan bir döndürürNSURLSessionTask. Tür açısından güvenli bir bağlamda olduğumuz için bir InvalidCastException gerçekleşir.

Üst bilgi açıklamasına uymak ve 'den InvalidCastException[ForcedTypeAttribute] kaçınmak için kullanılır.

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

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

, [ForcedTypeAttribute] varsayılan olarak [ForcedType (owns: true)]adlı Ownsfalse boole değerini de kabul eder. owns parametresi, Core Foundation nesneleri için Sahiplik İlkesi'ni izlemek için kullanılır.

[ForcedTypeAttribute] yalnızca parametrelerde, özelliklerde ve dönüş değerinde geçerlidir.

BindAsAttribute

, [BindAsAttribute]NSValue ve NSString(sabit listelerinin) daha doğru C# türlerine bağlanmasına NSNumberizin verir. özniteliği, yerel API üzerinden daha iyi, daha doğru .NET API'sini oluşturmak için kullanılabilir.

ile yöntemleri (dönüş değerinde), parametreleri ve özellikleri BindAssüsleyebilirsiniz. Tek kısıtlama, üyenizin bir [Protocol] veya [Model] arabiriminde olmaması gerektiğidir.

Örneğin:

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

Çıkış:

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

Dahili olarak ->NSNumber ve CGRect<-NSValue> dönüştürmelerini yapacağız.bool?<

Desteklenen geçerli kapsülleme türleri şunlardır:

  • NSValue
  • NSNumber
  • NSString

NSValue

Aşağıdaki C# veri türlerinin içinden/içine NSValuekapsüllenmesi desteklenir:

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

NSNumber

Aşağıdaki C# veri türlerinin içinden/içine NSNumberkapsüllenmesi desteklenir:

  • ikili
  • byte
  • çift
  • kayan noktalı sayı
  • short
  • int
  • uzun
  • sbyte
  • ushort
  • uint
  • ulong
  • nfloat
  • nint
  • nuint
  • Numaralandırmalar

NSString

[BindAs]daha iyi .NET API'sini oluşturmak için NSString sabiti tarafından desteklenen sabit listeleriyle birlikte çalışır, örneğin:

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

Çıkış:

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

-NSString> dönüştürmesini<enum yalnızca sağlanan sabit listesi türü [BindAs]bir NSString sabiti tarafından destekleniyorsa işleyeceğiz.

Diziler

[BindAs] ayrıca desteklenen türlerden herhangi birinin dizilerini de destekler. Örnek olarak aşağıdaki API tanımına sahip olabilirsiniz:

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

Çıkış:

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

rects parametresi, her CGRect biri için bir içeren bir NSValueNSArray içinde kapsüllenir ve karşılığında içeren döndürülen NSArrayNSStringsdeğerleri kullanılarak oluşturulmuş bir dizisi CAScroll? alırsınız.

Bindattribute

özniteliği, [Bind] bir yönteme veya özellik bildirimine uygulandığında iki, bir özellikteki tek tek alıcıya veya ayarlayıcıya uygulandığında bir tane daha kullanır.

Bir yöntem veya özellik için kullanıldığında özniteliğin [Bind] etkisi, belirtilen seçiciyi çağıran bir yöntem oluşturmaktır. Ancak sonuçta oluşturulan yöntem özniteliğiyle [Export] süslenmez, bu da geçersiz kılma yöntemine katılamadığını gösterir. Bu genellikle uzantı yöntemlerini uygulamak Objective-C için özniteliğiyle [Target] birlikte kullanılır.

Örneğin:

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

Bir getter veya ayarlayıcıda kullanıldığında özniteliği, [Bind] bir özellik için alıcı ve ayarlayıcı Objective-C seçici adları oluşturulurken kod oluşturucu tarafından çıkarsanan varsayılanları değiştirmek için kullanılır. Varsayılan olarak, adlı fooBarbir özelliğe bayrak eklediğinizde oluşturucu, alıcı ve setFooBar: ayarlayıcı için bir fooBar dışarı aktarma oluşturur. Birkaç durumda, Objective-C bu kurala uymaz, genellikle alıcı adını olarak isFooBardeğiştirirler. Oluşturucuya bunu bildirmek için bu özniteliği kullanırsınız.

Örneğin:

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

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

AsyncAttribute

Yalnızca Xamarin.iOS 6.3 ve daha yeni sürümlerde kullanılabilir.

Bu öznitelik, son bağımsız değişkenleri olarak tamamlama işleyicisi alan yöntemlere uygulanabilir.

Özniteliğini [Async] , son bağımsız değişkeni geri çağırma olan yöntemlerde kullanabilirsiniz. Bunu bir yönteme uyguladığınızda, bağlama oluşturucu sonekiyle Asyncbu yöntemin bir sürümünü oluşturur. Geri çağırma hiçbir parametre almazsa, geri çağırma bir Taskparametre alırsa, sonuç bir Task<T>olur.

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

Aşağıdakiler bu zaman uyumsuz yöntemi oluşturur:

Task LoadFileAsync (string file);

Geri çağırma birden çok parametre alıyorsa, oluşturulan türün ResultType istenen adını belirterek tüm özellikleri barındıracak veya ResultTypeName değerini ayarlamanız gerekir.

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

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

Aşağıdakiler, FileLoading hem byteCounthem de files erişim özellikleri içeren bu zaman uyumsuz yöntemi oluşturur:

Task<FileLoading> LoadFile (string file);

Geri çağırmanın son parametresi bir NSErrorise, oluşturulan Async yöntem değerin null olup olmadığını denetler ve böyle bir durumda, oluşturulan zaman uyumsuz yöntem görev özel durumunu ayarlar.

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

Yukarıdaki aşağıdaki zaman uyumsuz yöntemi oluşturur:

Task<string> UploadAsync (string file);

Ve hata durumunda, sonuçta elde edilen Görev, sonuçta NSErrorelde edilen öğesini sarmalayan bir NSErrorException özel durum olarak ayarlanır.

AsyncAttribute.ResultType

Dönen Task nesnenin değerini belirtmek için bu özelliği kullanın. Bu parametre mevcut bir tür alır, bu nedenle çekirdek API tanımlarınızdan birinde tanımlanması gerekir.

AsyncAttribute.ResultTypeName

Dönen Task nesnenin değerini belirtmek için bu özelliği kullanın. Bu parametre istediğiniz tür adının adını alır, oluşturucu geri çağırmanın aldığı her parametre için bir dizi özellik üretir.

AsyncAttribute.MethodName

Oluşturulan zaman uyumsuz yöntemlerin adını özelleştirmek için bu özelliği kullanın. Varsayılan, yöntemin adını kullanmak ve "Async" metnini eklemektir; bu varsayılanı değiştirmek için bunu kullanabilirsiniz.

DesignatedInitializerAttribute

Bu öznitelik bir oluşturucuya uygulandığında, son platform derlemesinde aynı [DesignatedInitializer] şekilde oluşturulur. Bu, IDE'nin alt sınıflarda hangi oluşturucunun kullanılması gerektiğini belirtmesine yardımcı olmaktır.

Bu, /clang kullanımı ile __attribute__((objc_designated_initializer))eşlenmelidirObjective-C.

DisableZeroCopyAttribute

Bu öznitelik dize parametrelerine veya dize özelliklerine uygulanır ve kod oluşturucuya bu parametre için sıfır kopya dize sıralamasını kullanmamasını ve bunun yerine C# dizesinden yeni bir NSString örneği oluşturmasını ister. Bu öznitelik yalnızca, oluşturucuya komut satırı seçeneğini kullanarak --zero-copy sıfır kopya dize hazırlamasını veya derleme düzeyi özniteliğini ayarlamasını ZeroCopyStringsAttributebildirirseniz dizelerde gereklidir.

Özelliğin bir özellik yerine copy veya assign özelliği olarak retain bildirildiği Objective-C durumlarda bu gereklidir. Bunlar genellikle geliştiriciler tarafından yanlış "iyileştirilmiş" üçüncü taraf kitaplıklarında gerçekleşir. Genel olarak veya retainassignNSString özellikleri yanlıştır çünkü NSMutableString veya kullanıcı tarafından türetilmiş sınıfları NSString , kitaplık kodu bilgisi olmadan dizelerin içeriğini değiştirebilir ve uygulamayı altta bozabilir. Bunun nedeni genellikle erken iyileştirmedir.

Aşağıda, içinde bu tür iki özellik gösterilmektedir Objective-C:

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

DisposeAttribute

bir sınıfa uyguladığınızda [DisposeAttribute] , sınıfının yöntem uygulamasına Dispose() eklenecek bir kod parçacığı sağlarsınız.

Dispose Yöntem araç tarafından otomatik olarak oluşturulduğundanbgen, oluşturulan Dispose yöntem uygulamasına [Dispose] kod eklemek için özniteliğini kullanmanız gerekir.

Örneğin:

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

Exportattribute

[Export] özniteliği, çalışma zamanına sunulacak bir yönteme veya özelliğe bayrak eklemek için Objective-C kullanılır. Bu öznitelik bağlama aracı ile gerçek Xamarin.iOS ve Xamarin.Mac çalışma zamanları arasında paylaşılır. Yöntemler için parametresi oluşturulan koda ayrıntılı olarak geçirilir; özellikler için temel bildirime göre bir alıcı ve ayarlayıcı Dışarı Aktarmaları oluşturulur (bağlama aracının davranışını değiştirme hakkında bilgi için üzerindeki bölümüne [BindAttribute] bakın).

Söz dizimi:

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; }
}

Seçici, bağlı olan temel Objective-C alınan yöntemin veya özelliğin adını temsil eder.

ExportAttribute.ArgumentSemantic

FieldAttribute

Bu öznitelik, C genel değişkenlerini isteğe bağlı olarak yüklenen ve C# koduna sunulan bir alan olarak kullanıma açmak için kullanılır. Genellikle bu, C ile tanımlanan veya Objective-C bazı API'lerde kullanılan belirteçler olabilen veya değerleri opak olan ve kullanıcı kodu tarafından olduğu gibi kullanılması gereken sabitlerin değerlerini almak için gereklidir.

Söz dizimi:

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, bağlanılacak C simgesidir. Varsayılan olarak bu, adı türün tanımlandığı ad alanından çıkarılan bir kitaplıktan yüklenir. Bu simgenin arandığı kitaplık değilse parametresini libraryName geçirmeniz gerekir. Statik bir kitaplığı bağlıyorsanız parametresi olarak libraryName kullanın__Internal.

Oluşturulan özellikler her zaman statik olacaktır.

Field özniteliğiyle bayrak eklenmiş özellikler aşağıdaki türlerden olabilir:

  • NSString
  • NSArray
  • nint / int / long
  • nuint / uint / ulong
  • nfloat / float
  • double
  • CGSize
  • System.IntPtr
  • Numaralandırmalar

Ayarlayıcılar NSString sabitleri tarafından desteklenen sabitler için desteklenmez, ancak gerekirse el ile bağlanabilirler.

Örnek:

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

InternalAttribute

[Internal] özniteliği yöntemlere veya özelliklere uygulanabilir ve oluşturulan kodu C# anahtar sözcüğüyle internal işaretleyerek kodun yalnızca oluşturulan derlemedeki kod için erişilebilir olmasını sağlar. Bu genellikle çok düşük düzeyli API'leri gizlemek veya oluşturucu tarafından desteklenmeyen ve bazı el kodlaması gerektiren API'ler için geliştirmek istediğiniz iyi olmayan bir genel API sağlamak için kullanılır.

Bağlamayı tasarlarken, genellikle bu özniteliği kullanarak yöntemi veya özelliği gizler ve yöntem veya özellik için farklı bir ad sağlarsınız ve ardından C# tamamlayıcı destek dosyanıza, temel alınan işlevselliği kullanıma sunan kesin olarak belirlenmiş bir sarmalayıcı eklersiniz.

Örneğin:

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

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

Ardından, destekleyici dosyanızda aşağıdakine benzer bir kodunuz olabilir:

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

IsThreadStaticAttribute

Bu öznitelik, .NET [ThreadStatic] özniteliğiyle ek açıklama eklenecek bir özelliğin yedekleme alanına bayrak ekler. Bu, alan bir iş parçacığı statik değişkeniyse kullanışlıdır.

MarshalNativeExceptions (Xamarin.iOS 6.0.6)

Bu öznitelik, yerel (Objective-C) özel durumları destekleyen bir yöntem oluşturur. Çağırma doğrudan çağırmak objc_msgSend yerine ObjectiveC özel durumlarını yakalayan ve bunları yönetilen özel durumlara sıralayan özel bir trambolin üzerinden geçer.

Şu anda yalnızca birkaç objc_msgSend imza desteklenmektedir (bağlamayı kullanan bir uygulamanın yerel bağlantısı eksik bir xamarin__objc_msgSend simgesiyle başarısız olduğunda bir imzanın desteklenip desteklenmediğini öğreneceksiniz), ancak istek üzerine daha fazla imza eklenebilir.

NewAttribute

Bu öznitelik, oluşturucunun bildirimin önünde anahtar sözcüğü oluşturmasını sağlamak için yöntemlere new ve özelliklere uygulanır.

Aynı yöntem veya özellik adı bir temel sınıfta zaten var olan bir alt sınıfta tanıtıldığında derleyici uyarılarından kaçınmak için kullanılır.

NotificationAttribute

Bu özniteliği alanlara uygulayarak oluşturucunun kesin olarak türlenmiş bir yardımcı Notifications sınıfı oluşturmasını sağlayabilirsiniz.

Bu öznitelik, yükü olmayan bildirimler için bağımsız değişkenler olmadan kullanılabilir veya API tanımında genellikle adı "EventArgs" ile biten başka bir arabirime başvuran bir System.Type belirtebilirsiniz. Oluşturucu, arabirimi alt sınıflara EventArgs dönüştürecek ve burada listelenen tüm özellikleri içerecektir. özniteliği, [Export] değeri getirmek için sözlüğü aramak Objective-C için kullanılan anahtarın adını listelemek için sınıfında kullanılmalıdırEventArgs.

Örneğin:

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

Yukarıdaki kod aşağıdaki yöntemlerle iç içe geçmiş bir sınıf MyClass.Notifications oluşturur:

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

Kodunuzun kullanıcıları aşağıdaki gibi bir kod kullanarak NSDefaultCenter'ne gönderilen bildirimlere kolayca abone olabilir:

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

Veya gözlemlemek üzere belirli bir nesne ayarlamak için. Bu yönteme objectToObserve geçerseniznull, diğer eşleri gibi davranır.

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

döndürülen değeri ObserveDidStart , aşağıdaki gibi bildirimleri almayı kolayca durdurmak için kullanılabilir:

token.Dispose ();

İsterseniz NSNotification.DefaultCenter.RemoveObserver öğesini çağırabilir ve belirteci geçirebilirsiniz. Bildiriminiz parametreler içeriyorsa aşağıdaki gibi bir yardımcı EventArgs arabirim belirtmeniz gerekir:

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; }
}

Yukarıdaki, anahtarları ScreenXKey kullanarak ve sırasıyla NSNotification.UserInfo sözlüğünden veri getiren ve ScreenY özelliklerine sahip ScreenX bir MyScreenChangedEventArgs sınıf oluşturur ve ScreenYKey uygun dönüştürmeleri uygular. [ProbePresence] anahtarı değerini ayıklamaya çalışmak yerine içinde UserInfoayarlanmışsa oluşturucunun yoklaması için özniteliği kullanılır. Bu, anahtarın varlığının değer olduğu durumlar için kullanılır (genellikle boole değerleri için).

Bu, aşağıdaki gibi bir kod yazmanızı sağlar:

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

Bazı durumlarda, sözlükte geçirilen değerle ilişkili bir sabit yoktur. Apple bazen genel sembol sabitlerini, bazen de dize sabitlerini kullanır. Varsayılan olarak [Export] , sağlanan EventArgs sınıfınızdaki öznitelik çalışma zamanında aranmak için ortak simge olarak belirtilen adı kullanır. Bu durum geçerli değilse ve bunun yerine dize sabiti olarak aranması gerekiyorsa, değeri Export özniteliğine geçirin ArgumentSemantic.Assign .

Xamarin.iOS 8.4'teki yenilikler

Bazen, bildirimler bağımsız değişken olmadan hayata başlar, bu nedenle bağımsız değişken olmadan kullanımı [Notification] kabul edilebilir. Ancak bazen bildirim parametreleri tanıtılır. Bu senaryoyu desteklemek için özniteliği birden çok kez uygulanabilir.

Bir bağlama geliştiriyorsanız ve mevcut kullanıcı kodunu bozmaktan kaçınmak istiyorsanız, mevcut bir bildirimi şu şekilde çevirebilirsiniz:

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

Bildirim özniteliğini iki kez listeleyen bir sürüme, örneğin:

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

NullAllowedAttribute

Bu bir özelliğe uygulandığında, değerin null kendisine atanmasına izin veren özelliğine bayrak ekler. Bu yalnızca başvuru türleri için geçerlidir.

Bu yöntem imzasında bir parametreye uygulandığında, belirtilen parametrenin null olabileceğini ve değerleri geçirmek null için hiçbir denetim gerçekleştirilmemesi gerektiğini gösterir.

Başvuru türü bu özniteliğe sahip değilse, bağlama aracı bu özniteliği geçirmeden Objective-C önce atanmakta olan değer için bir denetim oluşturur ve atanan nulldeğer ise atacak bir ArgumentNullException denetim oluşturur.

Örneğin:

// In properties

[NullAllowed]
UIImage IconFile { get; set; }

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

OverrideAttribute

Bağlama oluşturucuya bu belirli yöntem için bağlamanın bir override anahtar sözcükle işaretlenmesi gerektiğini bildirmek için bu özniteliği kullanın.

PreSnippetAttribute

Giriş parametreleri doğrulandıktan sonra, ancak kod çağrısından Objective-Cönce eklenecek kodu eklemek için bu özniteliği kullanabilirsiniz.

Örnek:

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

PrologueSnippetAttribute

Bu özniteliği kullanarak, oluşturulan yöntemde parametrelerden herhangi birinin doğrulanmasından önce eklenecek bazı kodlar ekleyebilirsiniz.

Örnek:

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

PostGetAttribute

Bağlama oluşturucusundan bir değer getirmek için bu sınıftan belirtilen özelliği çağırmasını bildirir.

Bu özellik genellikle başvurulmuş nesne grafını tutan nesnelere başvuran önbelleği yenilemek için kullanılır. Genellikle Ekle/Kaldır gibi işlemleri olan kodda gösterilir. Bu yöntem, öğeler eklendikten veya kaldırıldıktan sonra iç önbelleğin gerçekte kullanımda olan nesnelere yönetilen başvuruları tuttuğumuzdan emin olmak için güncelleştirilmesi için kullanılır. Bağlama aracı belirli bir bağlamadaki tüm başvuru nesneleri için bir yedekleme alanı oluşturduğundan bu mümkündür.

Örnek:

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

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

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

Bu durumda, nesneden Dependencies bağımlılıklar NSOperation eklendikten veya kaldırıldıktan sonra özellik çağrılır ve gerçek yüklenen nesneleri temsil eden bir graf elde ettiğimizden emin olur ve hem bellek sızıntılarını hem de bellek bozulmasını önler.

PostSnippetAttribute

Kod temel alınan Objective-C yöntemi çağırdıktan sonra eklenecek bazı C# kaynak kodunu eklemek için bu özniteliği kullanabilirsiniz

Örnek:

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

Proxyattribute

Bu öznitelik, değerleri proxy nesneleri olarak işaretlemek üzere döndürmek için uygulanır. Bazı Objective-C API'ler, kullanıcı bağlamalarından ayrıştırılmayan ara sunucu nesneleri döndürür. Bu özniteliğin etkisi, nesneyi nesne DirectBinding olarak işaretlemektir. Xamarin.Mac'teki bir senaryo için bu hatayla ilgili tartışmayı görebilirsiniz.

ReleaseAttribute (Xamarin.iOS 6.0)

Bu, oluşturucunun döndürmeden önce nesne üzerinde çağrısı Release yapması gerektiğini belirtmek için dönüş türlerine uygulanabilir. Bu yalnızca bir yöntem size korumalı bir nesne verdiğinde gereklidir (en yaygın senaryo olan otomatik olarak yayımlanan nesnenin aksine)

Örnek:

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

Ayrıca bu öznitelik oluşturulan koda yayılır, böylece Xamarin.iOS çalışma zamanı böyle bir işlevden geri döndükten Objective-C sonra nesneyi tutması gerektiğini bilir.

SealedAttribute

Oluşturucuya, oluşturulan yöntemi korumalı olarak işaretlemesini sağlar. Bu öznitelik belirtilmezse, varsayılan değer bir sanal yöntem (sanal yöntem, soyut yöntem veya diğer özniteliklerin nasıl kullanıldığına bağlı olarak geçersiz kılma) oluşturmaktır.

StaticAttribute

[Static] Özniteliği bir yönteme veya özelliğe uygulandığında, bu statik bir yöntem veya özellik oluşturur. Bu öznitelik belirtilmezse, oluşturucu bir örnek yöntemi veya özelliği üretir.

TransientAttribute

Değerleri geçici olan, yani iOS tarafından geçici olarak oluşturulan ancak uzun ömürlü olmayan nesnelere bayrak eklemek için bu özniteliği kullanın. Bu öznitelik bir özelliğe uygulandığında, oluşturucu bu özellik için bir yedekleme alanı oluşturmaz; bu da yönetilen sınıfın nesneye bir başvuru tutmadığı anlamına gelir.

WrapAttribute

Xamarin.iOS/Xamarin.Mac bağlamalarının tasarımında [Wrap] özniteliği, zayıf türdeki bir nesneyi kesin olarak belirlenmiş bir nesneyle sarmak için kullanılır. Bu çoğunlukla veya türünde idNSObjectolarak bildirilen temsilci nesneleriyle Objective-C devreye girer. Xamarin.iOS ve Xamarin.Mac tarafından kullanılan kural, bu temsilcileri veya veri kaynaklarını tür NSObject olarak kullanıma açmaktır ve "Weak" kuralı + kullanıma sunulan ad kullanılarak adlandırılır. özelliği id delegateObjective-C , API sözleşme dosyasında bir NSObject WeakDelegate { get; set; } özellik olarak gösterilebilir.

Ancak genellikle bu temsilciye atanan değer güçlü bir tür olduğundan, güçlü türü ortaya çıkarıyoruz ve özniteliğini uyguluyoruz [Wrap] . Bu, kullanıcıların bazı ince denetime ihtiyaçları varsa veya düşük düzeyli püf noktalarına başvurmaları gerekiyorsa zayıf türleri kullanmayı seçebileceği veya çalışmalarının çoğu için güçlü türdeki özelliği kullanabilecekleri anlamına gelir.

Örnek:

[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 ();
}

Kullanıcı, Temsilci'nin zayıf türdeki sürümünü bu şekilde kullanır:

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

}

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

Ve bu şekilde kullanıcı güçlü türdeki sürümü kullanır, kullanıcının C# türü sisteminden yararlandığını ve amacını bildirmek için override anahtar sözcüğünü kullandığına ve yöntemi ile [Export]el ile süslemesi gerekmediğine dikkat edin, çünkü biz bu işlemi kullanıcı için bağlamada yaptık:

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

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

özniteliğinin [Wrap] başka bir kullanımı, yöntemlerin kesin olarak türü belirlenmiş sürümünü desteklemektir. Örneğin:

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

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

[Wrap] Öznitelik, bir öznitelikle [Category] süslenmiş bir tür içindeki bir yönteme uygulandığında, uzantı yöntemi oluşturulduğundan ilk bağımsız değişken olarak eklemeniz This gerekir. Örneğin:

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

tarafından [Wrap] oluşturulan üyeler varsayılan olarak değildirvirtual, bir virtual üyeye ihtiyacınız varsa isteğe bağlı isVirtual parametresine true ayarlayabilirsiniz.

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

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

[Wrap] doğrudan özellik alıcılarında ve ayarlayıcılarında da kullanılabilir. Bu, bunlar üzerinde tam denetime sahip olmasını ve kodu gerektiği gibi ayarlamasını sağlar. Örneğin, akıllı sabit listeleri kullanan aşağıdaki API tanımını göz önünde bulundurun:

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

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

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

Arabirim tanımı:

// Property definition.

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

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

Parametre öznitelikleri

Bu bölümde, bir yöntem tanımındaki parametrelere uygulayabileceğiniz öznitelikler ve [NullAttribute] bir bütün olarak bir özellik için geçerli olan öznitelikler açıklanmaktadır.

BlockCallback

Bu öznitelik, bağlayıcıya söz konusu parametrenin blok çağırma kuralına uygun olduğunu ve bu şekilde hazırlaması gerektiğini bildirmek için C# temsilci bildirimlerindeki parametre türlerine Objective-C uygulanır.

Bu genellikle içinde Objective-Caşağıdaki gibi tanımlanan geri çağırmalar için kullanılır:

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

Ayrıca bkz. CCallback.

CCallback

Bu öznitelik, bağlayıcıya söz konusu parametrenin C ABI işlev işaretçisi çağırma kuralına uygun olduğunu ve bu şekilde hazırlaması gerektiğini bildirmek için C# temsilci bildirimlerindeki parametre türlerine uygulanır.

Bu genellikle içinde Objective-Caşağıdaki gibi tanımlanan geri çağırmalar için kullanılır:

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

Ayrıca bkz. BlockCallback.

Parametreler

Oluşturucunun [Params] tanıma bir "params" eklemesini sağlamak için yöntem tanımının son dizi parametresinde özniteliğini kullanabilirsiniz. Bu, bağlamanın isteğe bağlı parametrelere kolayca izin vermesine olanak tanır.

Örneğin, aşağıdaki tanım:

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

Aşağıdaki kodun yazılmasına izin verir:

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

Bu, kullanıcıların yalnızca öğeleri geçirmek için bir dizi oluşturmasını gerektirmemesi gibi ek bir avantaja sahiptir.

PlainString

Bağlama oluşturucusunun parametresini [PlainString]NSStringbir olarak geçirmek yerine dizeyi C dizesi olarak geçirmesini bildirmek için dize parametrelerinin önündeki özniteliğini kullanabilirsiniz.

Çoğu Objective-C API parametre kullanır NSString , ancak birkaç API, çeşitleme yerine dizeleri geçirmek için bir char * API'yi NSString kullanıma sunar. Bu durumlarda kullanın [PlainString] .

Örneğin, aşağıdaki Objective-C bildirimler:

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

Şu şekilde bağlanmalıdır:

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

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

RetainAttribute

Oluşturucuya belirtilen parametreye bir başvuru tutmasını belirtir. Oluşturucu bu alan için yedekleme deposu sağlar veya değerin depolanacağı adı ( WrapName) belirtebilirsiniz. Bu, parametresi olarak Objective-C geçirilen ve nesnenin yalnızca bu kopyasının tutulacağını bildiğiniz Objective-C bir yönetilen nesneye başvuru tutmak için yararlıdır. Örneğin, setDisplay aynı anda yalnızca bir nesne görüntüleyebileceğinden, gibi SetDisplay (SomeObject) bir API bu özniteliği kullanır. Birden fazla nesneyi (örneğin, Stack benzeri bir API) izlemeniz gerekiyorsa özniteliğini [RetainList] kullanırsınız.

Söz dizimi:

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

TransientAttribute

Bu öznitelik parametrelere uygulanır ve yalnızca C# öğesine geçiş Objective-C yapılırken kullanılır. Bu geçişler sırasında çeşitli Objective-CNSObject parametreler nesnenin yönetilen gösterimine sarmalanmıştır.

Çalışma zamanı yerel nesneye başvuru alır ve nesneye son yönetilen başvuru gidene kadar başvuruyu tutar ve GC'nin çalışma şansı olur.

Birkaç durumda, C# çalışma zamanının yerel nesneye bir başvuru tutmaması önemlidir. Bu durum bazen temel alınan yerel kod parametresinin yaşam döngüsüne özel bir davranış eklediğinde ortaya çıkar. Örneğin: parametresinin yıkıcısı bazı temizleme eylemleri gerçekleştirir veya bazı değerli kaynakları atar.

Bu öznitelik çalışma zamanına, üzerine yazılan yönteminizden geri Objective-C dönerken mümkünse nesnenin atılmasını istediğinizi bildirir.

Kural basittir: Çalışma zamanının yerel nesneden yeni bir yönetilen gösterim oluşturması gerekiyorsa, işlevin sonunda yerel nesnenin saklama sayısı bırakılır ve yönetilen nesnenin Handle özelliği temizlenir. Bu, yönetilen nesneye bir başvuru tutarsanız bu başvurunun işe yaramaz hale geleceği anlamına gelir (üzerindeki yöntemleri çağırmak bir özel durum oluşturur).

Geçirilen nesne oluşturulmadıysa veya nesnenin bekleyen bir yönetilen gösterimi zaten varsa, zorlamalı atma gerçekleşmez.

Özellik öznitelikleri

NotImplementedAttribute

Bu öznitelik, bir getter ile bir özelliğin temel sınıfta tanıtıldığı ve değiştirilebilir bir alt sınıfın bir ayarlayıcı tanıttığı bir deyimi desteklemek Objective-C için kullanılır.

C# bu modeli desteklemediğinden, temel sınıfın hem ayarlayıcıya hem de alıcıya sahip olması gerekir ve bir alt sınıf OverrideAttribute'u kullanabilir.

Bu öznitelik yalnızca özellik ayarlayıcılarında kullanılır ve içinde Objective-Cdeğiştirilebilir deyimi desteklemek için kullanılır.

Örnek:

[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; }
}

Sabit listesi öznitelikleri

Sabitleri numaralandırma değerlerine eşlemek NSString , daha iyi .NET API'sini oluşturmanın kolay bir yoludur. Bu:

  • yalnızca API için doğru değerleri göstererek kod tamamlamanın daha kullanışlı olmasını sağlar;
  • tür güvenliği ekler, yanlış bağlamda başka bir NSString sabit kullanamazsınız; ve
  • bazı sabitleri gizlemeye olanak tanır ve işlev kaybı olmadan kod tamamlamanın daha kısa API listesini göstermesini sağlar.

Örnek:

enum NSRunLoopMode {

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

    [Field ("NSRunLoopCommonModes")]
    Common,

    [Field (null)]
    Other = 1000
}

Yukarıdaki bağlama tanımından oluşturucu kendisini oluşturur enum ve sabitler ile sabitler NSString arasında iki yönlü dönüştürme yöntemleri içeren statik bir *Extensions tür de oluşturur. Bu, sabitlerin API'nin parçası olmasalar bile geliştiricilerin kullanımına açık kaldığı anlamına gelir.

Örnekler:

// 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

Bu öznitelikle bir sabit listesi değerini süsleyebilirsiniz. Sabit listesi değeri bilinmiyorsa bu, döndürülen sabit haline gelir.

Yukarıdaki örnekten:

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

Hiçbir sabit listesi değeri dekore edilmediyse, bir NotSupportedException oluşturulur.

ErrorDomainAttribute

Hata kodları bir sabit listesi değerleri olarak bağlıdır. Genellikle bunlar için bir hata etki alanı vardır ve hangisinin geçerli olduğunu (veya varsa) bulmak her zaman kolay değildir.

Hata etki alanını sabit listesiyle ilişkilendirmek için bu özniteliği kullanabilirsiniz.

Örnek:

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

Daha sonra uzantı yöntemini GetDomain çağırarak herhangi bir hatanın etki alanı sabitini alabilirsiniz.

FieldAttribute

Bu, türün içindeki sabitler için kullanılan öznitelikle aynıdır [Field] . Bir değeri belirli bir sabitle eşlemek için sabit listelerinin içinde de kullanılabilir.

Sabit null belirtilirse hangi sabit listesi değerinin döndürüleceğini belirtmek için bir nullNSString değer kullanılabilir.

Yukarıdaki örnekten:

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

Değer yoksa null bir ArgumentNullException oluşturulur.

Genel öznitelikler

Genel öznitelikler veya gibi [LinkWithAttribute] öznitelik değiştirici kullanılarak uygulanır [assembly:] veya kullanılabilirlik öznitelikleri gibi her yerde kullanılabilir.

LinkWithAttribute

Bu, geliştiricilerin, kitaplığın tüketicisini kitaplığa geçirilen gcc_flags ve ek mtouch bağımsız değişkenlerini el ile yapılandırmaya zorlamadan bağlı bir kitaplığı yeniden kullanmak için gereken bağlama bayraklarını belirtmesine olanak tanıyan bir derleme düzeyi özniteliğidir.

Söz dizimi:

// 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; }
}

Bu öznitelik derleme düzeyinde uygulanır, örneğin CorePlot bağlamaları bunu kullanır:

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

özniteliğini [LinkWith] kullandığınızda, belirtilen libraryName sonuç derlemesine eklenir ve kullanıcıların hem yönetilmeyen bağımlılıkları hem de Xamarin.iOS kitaplığını düzgün bir şekilde kullanmak için gereken komut satırı bayraklarını içeren tek bir DLL göndermesine olanak sağlar.

Bir sağlamamak libraryNameda mümkündür, bu durumda LinkWith özniteliği yalnızca ek bağlayıcı bayrakları belirtmek için kullanılabilir:

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

LinkWithAttribute oluşturucuları

Bu oluşturucular, bağlantı kurulacak ve sonuçta elde edilen derlemenize eklenecek kitaplığı, kitaplığın desteklediği desteklenen hedefleri ve kitaplıkla bağlantı oluşturmak için gereken isteğe bağlı kitaplık bayraklarını belirtmenize olanak tanır.

Bağımsız değişkeninin LinkTarget Xamarin.iOS tarafından çıkarıldığını ve ayarlanması gerekmediğini unutmayın.

Örnekler:

// 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 özelliği, yerel kitaplığı bağlamak için bağlantı bayrağının -force_load kullanılıp kullanılmadığına karar vermek için kullanılır. Şimdilik, bu her zaman doğru olmalıdır.

LinkWithAttribute.Frameworks

Bağlı olan kitaplığın herhangi bir çerçevede (ve UIKitdışındaFoundation) zor bir gereksinimi varsa, özelliğini gerekli platform çerçevelerinin boşlukla ayrılmış listesini içeren bir dizeye ayarlamanız Frameworks gerekir. Örneğin, ve CoreTextgerektiren CoreGraphics bir kitaplığı bağlarsanız özelliğini olarak "CoreGraphics CoreText"ayarlayabilirsinizFrameworks.

LinkWithAttribute.IsCxx

Sonuçta elde edilen yürütülebilir dosyanın C derleyicisi olan varsayılan yerine bir C++ derleyicisi kullanılarak derlenmesi gerekiyorsa bu özelliği true olarak ayarlayın. Bağladığınız kitaplık C++ dilinde yazılmışsa bunu kullanın.

LinkWithAttribute.LibraryName

Paketlenen yönetilmeyen kitaplığın adı. Bu, ".a" uzantısına sahip bir dosyadır ve birden çok platform için nesne kodu içerebilir (örneğin, simülatör için ARM ve x86).

Xamarin.iOS'un önceki sürümleri, kitaplığınızın desteklediği platformu belirlemek için özelliği denetledi LinkTarget , ancak bu artık otomatik olarak algılanır ve LinkTarget özellik yoksayılır.

LinkWithAttribute.LinkerFlags

Dize, LinkerFlags bağlama yazarlarının yerel kitaplığı uygulamaya bağlarken gereken ek bağlayıcı bayraklarını belirtmesi için bir yol sağlar.

Örneğin, yerel kitaplık libxml2 ve zlib gerektiriyorsa, dizesini LinkerFlags olarak "-lxml2 -lz"ayarlarsınız.

LinkWithAttribute.LinkTarget

Xamarin.iOS'un önceki sürümleri, kitaplığınızın desteklediği platformu belirlemek için özelliği denetledi LinkTarget , ancak bu artık otomatik olarak algılanır ve LinkTarget özellik yoksayılır.

LinkWithAttribute.NeedsGccExceptionHandling

Bağladığınız kitaplık GCC Özel Durum İşleme kitaplığını (gcc_eh) gerektiriyorsa bu özelliği true olarak ayarlayın

SmartLink Xamarin.iOS'un gerekli olup olmadığını ForceLoad belirlemesine izin vermek için özelliği true olarak ayarlanmalıdır.

LinkWithAttribute.WeakFrameworks

WeakFrameworks özelliği özelliğiyle Frameworks aynı şekilde çalışır, ancak bağlantı zamanında -weak_framework tanımlayıcı listelenen çerçevelerin her biri için gcc'ye geçirilir.

WeakFrameworks kitaplıkların ve uygulamaların platform çerçevelerine karşı zayıf bir şekilde bağlantı oluşturmasını mümkün kılar, böylece kullanılabilir olduklarında isteğe bağlı olarak kullanabilirler, ancak kitaplığınız iOS'un daha yeni sürümlerine ek özellikler eklemek için kullanılıyorsa bu yararlı olacaktır. Zayıf bağlama hakkında daha fazla bilgi için Apple'ın Zayıf Bağlama belgelerine bakın.

Zayıf bağlama için iyi adaylar Hesaplar, CoreBluetooth, CoreImage, GLKitNewsstandKit ve Twitter gibi olabilir Frameworks çünkü bunlar yalnızca iOS 5'te kullanılabilir.

ÖneriAttribute

Geliştiricilere kullanmaları daha uygun olabilecek diğer API'ler hakkında ipucu vermek için bu özniteliği kullanın. Örneğin, bir API'nin kesin olarak türü belirlenmiş bir sürümünü sağlarsanız, bu özniteliği zayıf türü belirlenmiş öznitelikte kullanarak geliştiriciyi daha iyi API'ye yönlendirebilirsiniz.

Bu öznitelikteki bilgiler belgelerde gösterilir ve kullanıcılara nasıl geliştirileceği konusunda öneriler sunmak için araçlar geliştirilebilir

RequiresSuperAttribute

Bu, geliştiriciye bir yöntemi geçersiz kılmanın [Advice] temel (geçersiz kılınan) yöntemine bir çağrı gerektirdiğini ima etmek için kullanılabilecek özel bir öznitelik alt sınıfıdır.

Bu, clang__attribute__((objc_requires_super))

ZeroCopyStringsAttribute

Yalnızca Xamarin.iOS 5.4 ve daha yeni sürümlerde kullanılabilir.

Bu öznitelik, oluşturucuya bu özel kitaplık için bağlamanın (ile [assembly:]uygulanmışsa) veya türün hızlı sıfır kopya dize sıralamasını kullanması gerektiğini gösterir. Bu öznitelik, komut satırı seçeneğini --zero-copy oluşturucuya geçirmekle eşdeğerdir.

Oluşturucu, dizeler için sıfır kopya kullanırken, yeni NSString bir nesne oluşturmadan ve C# dizelerindeki verileri dizeye Objective-C kopyalamaktan kaçınmadan tüketen dizeyle aynı C# dizesini Objective-C etkili bir şekilde kullanır. Sıfır Kopyalama dizelerini kullanmanın tek dezavantajı, sarmaladığınız herhangi bir dize özelliğinin olarak retain işaretlendiğinden veya copy öznitelik kümesine [DisableZeroCopy] sahip olduğundan emin olmanız gerekir. Bunun nedeni, sıfır kopya dizelerinin tanıtıcısının yığında ayrılması ve işlev dönüşünde geçersiz olmasıdır.

Örnek:

[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; }
}

Özniteliği derleme düzeyinde de uygulayabilirsiniz ve tüm derleme türlerine uygulanır:

[assembly:ZeroCopyStrings]

Kesin türemiş sözlükler

Xamarin.iOS 8.0 ile kolayca sarmalayan NSDictionariesgüçlü türe sahip sınıflar oluşturmaya yönelik desteği kullanıma sunuyoruz.

DictionaryContainer veri türünü el ile API ile birlikte kullanmak her zaman mümkün olsa da, bunu yapmak artık çok daha kolaydır. Daha fazla bilgi için bkz . Güçlü Türlerde Gezinme.

StrongDictionary

Bu öznitelik bir arabirime uygulandığında, oluşturucu DictionaryContainer'dan türetilen arabirimle aynı ada sahip bir sınıf oluşturur ve arabirimde tanımlanan her özelliği sözlük için kesin olarak yazılmış bir alıcı ve ayarlayıcıya dönüştürür.

Bu, var olan NSDictionary veya yeni oluşturulan bir sınıftan örneği oluşturulabilen bir sınıfı otomatik olarak oluşturur.

Bu öznitelik, sözlük üzerindeki öğelere erişmek için kullanılan anahtarları içeren sınıfın adı olan bir parametre alır. Varsayılan olarak özniteliğine sahip arabirimdeki her özellik, "Anahtar" son ekine sahip bir ad için belirtilen türdeki bir üyeyi arar.

Örneğin:

[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; }
}

Yukarıdaki durumda, MyOption sınıfı için bir dize özelliği oluşturur ve bu özellik bir dizeyi almak için Name sözlüğünde anahtarı olarak kullanır MyOptionKeys.NameKey . Ve bir int içeren bir NSNumber almak için sözlük anahtarı olarak kullanırMyOptionKeys.AgeKey.

Farklı bir anahtar kullanmak istiyorsanız, özelliğinde export özniteliğini kullanabilirsiniz, örneğin:

[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; }
}

Güçlü sözlük türleri

Tanımda StrongDictionary aşağıdaki veri türleri desteklenir:

C# Arabirim Türü NSDictionaryDepolama Türü
bool Boolean bir NSNumber
Numaralandırma değerleri içinde depolanan tamsayı NSNumber
int bir içinde depolanan 32 bit tamsayı NSNumber
uint bir içinde depolanan 32 bit işaretsiz tamsayı NSNumber
nint NSInteger bir NSNumber
nuint NSUInteger bir NSNumber
long Bir içinde depolanan 64 bit tamsayı NSNumber
float 32 bit tamsayı olarak depolanır NSNumber
double 64 bit tamsayı olarak depolanır NSNumber
NSObject ve alt sınıflar NSObject
NSDictionary NSDictionary
string NSString
NSString NSString
C# Array / NSObject NSArray
Numaralandırmaların C# Array sayısı NSArraydeğerleri içeren NSNumber