registrar Xamarin.iOS için Tür
Bu belge, Xamarin.iOS tarafından kullanılan tür kayıt sistemini açıklar.
Yönetilen sınıfların ve yöntemlerin kaydı
Başlatma sırasında Xamarin.iOS şunları kaydedecek:
- Sınıf olarak [Register] özniteliğine sahip sınıflar.
- Kategori olarak [Category] özniteliğine sahip sınıflar.
- Protokol olarak [Protocol] özniteliğine sahip arabirimler.
- [Dışarı Aktarma] olan üyeler,bu üyelere erişmeyi mümkün halelar.
Örneğin, Main Xamarin.iOS uygulamalarında yaygın olarak kullanılan yönetilen yöntemi göz önünde bulundurabilirsiniz:
UIApplication.Main (args, null, "AppDelegate");
Bu kod, Objective-C çalışma zamanının uygulamanın temsilci sınıfı AppDelegate olarak adlandırılan türü kullanmalarını söyler. Çalışma Objective-C zamanının C# sınıfının bir örneğini oluşturabilecek AppDelegate olması için bu sınıfın kayıtlı olması gerekir.
Xamarin.iOS, kaydı çalışma zamanında (dinamik kayıt) veya derleme zamanında (statik kayıt) otomatik olarak gerçekleştirir.
Dinamik kayıt başlangıçta yansımayı kullanarak kaydedilen tüm sınıfları ve yöntemleri bulur ve bunları çalışma zamanlarına Objective-C iletir. Simülatör derlemeleri için varsayılan olarak dinamik kayıt kullanılır.
Statik kayıt, derleme zamanında uygulama tarafından kullanılan derlemeleri inceler. Ile kaydedilen sınıfları ve yöntemleri belirler ve ikili Objective-C dosyanıza eklenmiş bir eşleme üretir. Ardından, başlangıçta eşlemeyi çalışma zamanı ile Objective-C kaydedmektedir. Cihaz derlemeleri için statik kayıt kullanılır.
Kategoriler
Xamarin.iOS 8.10'dan başlayarak C# söz dizimi Objective-C kullanarak kategoriler oluşturmak mümkündür.
Bir kategori oluşturmak için özniteliğini [Category] kullanın ve genişletecek türü belirtin. Örneğin, aşağıdaki kod NSString genişletildi:
[Category (typeof (NSString))]
Bir kategorinin yöntemlerinin her biri bir [Export] özniteliğine sahip ve çalışma zamanı tarafından kullanılabilir Objective-C hale geldi:
[Export ("today")]
public static string Today ()
{
return "Today";
}
Tüm yönetilen uzantı yöntemleri statik olmalıdır, ancak uzantı yöntemleri için standart C# söz dizimi kullanılarak Objective-C örnek yöntemleri oluşturmak mümkündür:
[Export ("toUpper")]
public static string ToUpper (this NSString self)
{
return self.ToString ().ToUpper ();
}
Genişletme yönteminin ilk bağımsız değişkeni, yönteminin çağrıldı olduğu örnektir:
[Category (typeof (NSString))]
public static class MyStringCategory
{
[Export ("toUpper")]
static string ToUpper (this NSString self)
{
return self.ToString ().ToUpper ();
}
}
Bu örnek, sınıfına toUpper bir yerel örnek yöntemi NSString ekler. Bu yöntem, yönteminden çağrıl Objective-C olabilir:
[Category (typeof (UIViewController))]
public static class MyViewControllerCategory
{
[Export ("shouldAutoRotate")]
static bool GlobalRotate ()
{
return true;
}
}
Protokoller
Xamarin.iOS 8.10'dan başlayarak, özniteliğine sahip arabirimler protokol [Protocol]Objective-C olarak 'ye dışarı aktarıldı:
[Protocol ("MyProtocol")]
interface IMyProtocol
{
[Export ("method")]
void Method ();
}
class MyClass : IMyProtocol
{
void Method ()
{
}
}
Bu kod, IMyProtocol adlı bir protokol ve protokol Objective-CMyProtocol uygulayan adlı bir sınıf olarak dışarı MyClass aktarıyor.
Yeni kayıt sistemi
Kararlı 6.2.6 sürümü ve beta 6.3.4 sürümünden başlayarak yeni bir statik registrar ekledik. 7.2.1 sürümünde, yeni varsayılanı registrar yaptık.
Bu yeni kayıt sistemi aşağıdaki yeni özellikleri sunar:
Programcı hatalarının derleme zamanı algılaması:
- Aynı adla kaydedilen iki sınıf.
- Aynı seçiciye yanıt vermek için dışarı aktarıldı birden fazla yöntem
Kullanılmayan yerel kodun kaldırılması:
- Yeni kayıt sistemi statik kitaplıklarda kullanılan koda güçlü başvurular ekler ve bu da yerel bağlantıcıya elde edilen ikili dosyadan kullanılmayan yerel kodu çıkartır. Xamarin'in örnek bağlamalarında çoğu uygulama en az 300 bin daha küçük hale geldi.
genel alt sınıfları için
NSObjectdestek; daha fazlaNSObjectAdları. Buna ek olarak, yeni kayıt sistemi daha önce çalışma zamanında rastgele davranışa neden olan desteklenmeyen genel yapıları yakalar.
tarafından yakalanan hatalarla ilgili registrar
Aşağıda yeni tarafından yakalanan hatalara bazı örnekler registrar verilmiştir.
Aynı seçiciyi aynı sınıfta birden çok kez dışarı aktarma:
[Register] class MyDemo : NSObject { [Export ("foo:")] void Foo (NSString str); [Export ("foo:")] void Foo (string str) }Aynı adla birden fazla yönetilen sınıfı dışarı Objective-C aktarma:
[Register ("Class")] class MyClass : NSObject {} [Register ("Class")] class YourClass : NSObject {}Genel yöntemleri dışarı aktarma:
[Register] class MyDemo : NSObject { [Export ("foo")] void Foo<T> () {} }
Sınırlamalar registrar
Yeni ile ilgili olarak göz gereken bazı registrar şeyler:
Bazı üçüncü taraf kitaplıkların yeni kayıt sistemiyle çalışacak şekilde güncelleştirilmiş olması gerekir. Diğer ayrıntılar için aşağıdaki gerekli değişikliklere bakın.
Kısa vadeli bir dezavantajı, Accounts çerçevesi kullanılıyorsa Clang'nin de kullanılmalıdır (bunun nedeni Apple'ın accounts.h üst bilgisi yalnızca Clang tarafından derlenmiş olmasıdır). Xcode 4.6 veya önceki bir sürüm kullanıyorsanız Clang'yi kullanmak için ek mtouch bağımsız değişkenlerine ekleyin
--compiler:clang(Xamarin.iOS otomatik olarak Xcode 5.0 veya sonraki sürümlerinde Clang'yi seçer.)Xcode 4.6 (veya önceki bir sürümü) kullanılıyorsa, dışarı aktaran tür adları ASCII olmayan karakterler içeriyorsa GCC/G++ seçilmelidir (bunun nedeni, Xcode 4.6 ile gönderilen Clang sürümünün kod içindeki tanımlayıcıların içinde ASCII olmayan karakterleri desteklememiş Objective-C olmasıdır). Diğer
--compiler:gccmtouch bağımsız değişkenlerini kullanarak GCC.
Seçerek registrar
Projenin iOS Derleme ayarlarında ek mtouch bağımsız değişkenlerine aşağıdaki seçeneklerden birini registrar ekleyerek farklı bir değer registrar
--registrar:static– cihaz derlemeleri için varsayılan--registrar:dynamic– simülatör derlemeleri için varsayılan
Not
Xamarin'in Classic API ve gibi diğer seçenekleri --registrar:legacystatic--registrar:legacydynamic desteklemişti. Ancak, bu seçenekler aşağıdakiler tarafından Unified API.
Eski kayıt sistemiyle ilgili eksiklikler
Eski kayıt sisteminin aşağıdaki dezavantajları vardır:
- Üçüncü taraf yerel kitaplıklarda sınıflara ve yöntemlere (yerel) statik başvuru yoktu, yani yerel bağlantıcıdan aslında kullanılmayan üçüncü taraf yerel kodu kaldırmalarını isteyemedik (çünkü her şey kaldırılacak). Objective-C Bu, her üçüncü taraf bağlamanın (veya özniteliğinde
-force_load libNative.aeşdeğerini)ForceLoad=trueyapmalarının[LinkWith]nedenidir. - Uyarı vermeden aynı adla iki yönetilen Objective-C türü dışarı aktarın. Nadir bir senaryo, farklı ad alanlarında iki
AppDelegatesınıfa sahip olmaktır. Çalışma zamanında, hangisinin seçilene kadar tamamen rastgele olması gerekir (aslında, çok şaşırtıcı ve can sıkıcı bir hata ayıklama deneyimi için yapılan, daha önce bile yeniden oluşturulmuş bir uygulamanın çalıştırmaları arasında farklıydı). - Aynı imzaya sahip iki yöntemi dışarı Objective-C aktarın. Yine hangisinin rastgele olduğunu da ifade etmek gerekirse (ancak bu sorun önceki sorun kadar yaygın değildi çünkü bu hatayla gerçekten yaşamanın tek yolu şanssız yönetilen yöntemi geçersiz Objective-C kılmaktı).
- Dışarı aktaran yöntem kümesi, dinamik ve statik derlemeler arasında biraz farklıydı.
- Genel sınıflar dışarı aktarıldıklarında düzgün çalışmaz (çalışma zamanında yürütülen tam genel uygulama rastgele olur ve bu da belirlenemeyen davranışa neden olur).
registrar Yeni: bağlamalarda gerekli değişiklikler
Bu bölümde, yeni ile çalışmak için yapılacak bağlama değişiklikleri açık registrar almaktadır.
Protokoller [Protocol] özniteliğine sahip olmalı
Protokollerin artık özniteliğine sahip olması [Protocol] gerekir. Bunu yapmasanız, aşağıdakiler gibi bir yerel bağlantı hatası alırsınız:
Undefined symbols for architecture i386: "_OBJC_CLASS_$_ProtocolName", referenced from: ...
Seçiciler geçerli sayıda parametreye sahip olmalıdır
Tüm seçicilerin parametre sayısını doğru şekilde belirterek belirt olması gerekir. Daha önce bu hatalar yoksayılıyor ve çalışma zamanı sorunlarına neden olabilir.
Kısacası iki nokta sayısının parametre sayısıyla eşleşmesi gerekir:
- Parametre yok:
foo - Bir parametre:
foo: - İki parametre:
foo:parameterName2:
Aşağıdakiler yanlış kullanımlardır:
// Invalid: export takes no arguments, but function expects one
[Export ("apply")]
void Apply (NSObject target);
// Invalid: exported as taking an argument, but the managed version does not have one:
[Export ("display:")]
void Display ();
Dışarı Aktarma'da IsVariadic parametresini kullanma
Variadic işlevlerinin özniteliği için IsVariadic bağımsız değişken kullanması [Export] gerekir:
[Export ("variadicMethod:", IsVariadic = true)]
void VariadicMethod (NSObject first, IntPtr subsequent);
Mevcut sembollere bağlantı gerekir
Yerel kitaplıkta mevcut olmayan sınıfları bağlamak mümkün değildir. Yerel kitaplıkta bir sınıf kaldırılmış veya yeniden adlandırılmışsa, bağlamaları eşleşmesi için güncelleştirin.