바인딩 형식 참조 가이드
이 문서에서는 바인딩을 구동하기 위해 API 계약 파일에 주석을 추가하는 데 사용할 수 있는 특성 목록과 생성된 코드에 대해 설명합니다.
Xamarin.iOS 및 Xamarin.Mac API 계약은 주로 코드가 C#에 표시되는 방식을 Objective-C 정의하는 인터페이스 정의로 C#으로 작성됩니다. 프로세스에는 인터페이스 선언과 API 계약에 필요할 수 있는 몇 가지 기본 형식 정의가 혼합됩니다. 바인딩 형식에 대한 소개는 도우미 가이드 바인딩 Objective-C 라이브러리를 참조하세요.
형식 정의
구문:
[BaseType (typeof (BTYPE))
interface MyType : [Protocol1, Protocol2] {
IntPtr Constructor (string foo);
}
특성이 있는 계약 정의의 [BaseType]
모든 인터페이스는 생성된 개체의 기본 형식을 선언합니다. 위의 선언 MyType
에서 클래스 C# 형식이 호출MyType
된 형식에 Objective-C 바인딩되는 생성됩니다.
인터페이스 Protocol1
Protocol2
상속 구문을 사용하여 형식 이름 뒤의 형식을 지정하면 해당 인터페이스의 내용이 계약의 MyType
일부인 것처럼 인라인됩니다.
Xamarin.iOS에서 형식이 프로토콜을 채택하는 것처럼 표시되는 방식은 프로토콜에서 선언된 모든 메서드와 속성을 형식 자체에 인라인하는 것입니다.
다음은 Xamarin.iOS 계약에서 선언 UITextField
을 정의하는 방법을 Objective-C 보여줍니다.
@interface UITextField : UIControl <UITextInput> {
}
다음과 같이 C# API 계약으로 작성됩니다.
[BaseType (typeof (UIControl))]
interface UITextField : UITextInput {
}
인터페이스에 다른 특성을 적용하고 특성을 구성 [BaseType]
하여 코드 생성의 다른 여러 측면을 제어할 수 있습니다.
이벤트 생성
Xamarin.iOS 및 Xamarin.Mac API 디자인의 한 가지 기능은 대리자 클래스를 C# 이벤트 및 콜백으로 매핑 Objective-C 한다는 것입니다. 사용자는 런타임에서 호출하는 다양한 메서드 Objective-C 를 구현하는 클래스의 인스턴스와 같은 Delegate
속성에 할당하거나 C#스타일 이벤트 및 속성을 선택하여 프로그래밍 패턴을 채택 Objective-C 할지 여부를 인스턴스별로 선택할 수 있습니다.
모델을 사용하는 방법의 한 가지 예를 살펴보겠습니다.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 ();
}
}
위의 예제에서는 두 메서드를 덮어쓰도록 선택한 것을 볼 수 있습니다. 하나는 스크롤 이벤트가 발생했음을 알리는 알림이고, 두 번째는 위로 스크롤해야 하는지 여부를 지시하는 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
클래스를 연결하는 이벤트 및 속성을 생성하도록 지원합니다(모델 클래스라고도 함). 이 작업은 정의 Events
에 및 Delegates
매개 변수에 주석을 [BaseType]
추가하여 수행됩니다(아래 설명 참조).
이러한 매개 변수에 주석을 [BaseType]
추가하는 것 외에도 몇 가지 구성 요소를 생성기에 알려야 합니다.
둘 이상의 매개 변수를 사용하는 이벤트의 경우( Objective-C 규칙에 따라 대리자 클래스의 첫 번째 매개 변수가 보낸 사람 개체의 인스턴스임) 생성된 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]
생성기가 호출에서 지정된 매개 변수의 값을 반환하도록 지시하는 특성 또는 [NoDefaultValue]
생성기에 기본값이 없음을 지시하는 매개 변수를 사용할 [DefaultValueFromArgument]
수도 있습니다.
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
일반적으로 Delegate
인스턴스 BarcodeScannerDelegate
를 할당할 속성이 있지만, 이 속성은 작동하지만 사용자에게 C#과 유사한 스타일 이벤트 인터페이스를 노출할 수 있으며, 이러한 경우 특성의 속성과 Delegates
속성을 [BaseType]
사용할 Events
수 있습니다.
이러한 속성은 항상 함께 설정되며 요소 수가 같아야 하며 동기화된 상태로 유지되어야 합니다. 배열에는 Delegates
래핑하려는 약한 형식의 각 대리자마다 하나의 문자열이 포함되며 Events
, 배열에는 연결하려는 각 형식에 대해 하나의 형식이 포함됩니다.
[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
이 특성이 인터페이스 정의에 적용되면 기본(생성된) 생성자에 대한 특성이 생성 [DesignatedInitializer]
되며 이는 선택기로 init
매핑됩니다.
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
가 필요하지만 ObjC 정적 확장을 바인딩하는 확장을 사용하기 BoolMethod
때문에 잘못된 것입니다. 이는 C# 확장 메서드가 구현되는 방식 때문에 부작용이 발생합니다.
위의 정의를 사용하는 유일한 방법은 다음과 같은 못생긴 코드입니다.
(null as FooObject).BoolMethod (range);
이를 방지하기 위한 권장 사항은 인터페이스 정의 자체 내의 BoolMethod
FooObject
정의를 인라인하는 것입니다. 이렇게 하면 의도한 FooObject.BoolMethod (range)
대로 이 확장을 호출할 수 있습니다.
[BaseType (typeof (NSObject))]
interface FooObject {
[Static]
[Export ("boolMethod:")]
bool BoolMethod (NSRange range);
}
정의 내에서 멤버를 찾을 [Static]
때마다 경고(BI1117)를 [Category]
실행합니다. 정의 내에 [Category]
멤버가 실제로 있도록 [Static]
하려면 멤버 또는 [Category]
인터페이스 정의를 사용하여 [Category (allowStaticMembers: true)]
또는 데코레이팅하여 경고를 무음으로 [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
호출해서는 안 됨을 의미합니다. 해당 메서드를 호출하면 다음과 같은 예외가 throw됩니다. 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
하지 않은 경우 반환 값은 진행률 매개 변수에 전달된 값입니다.
참고 항목: [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
이 특성은 생성기가 호스트 클래스에서 생성된 속성의 이름을 변경할 수 있도록 하는 데 사용됩니다. 경우에 따라 FooDelegate 클래스 메서드의 이름이 Delegate 클래스에 적합하지만 호스트 클래스에서 속성으로 이상하게 보일 때 유용합니다.
또한 FooDelegate 클래스에서와 같이 이름을 유지하는 것이 합리적이지만 더 나은 이름의 호스트 클래스에 노출하려는 두 개 이상의 오버로드 메서드가 있는 경우 이 방법이 매우 유용하고 필요합니다.
예시:
[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 규칙에 대리자 클래스의 첫 번째 매개 변수가 보낸 사람 개체의 인스턴스임) 생성된 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);
위의 내용은 다음의 UIWebViewDelegate
메서드로 노출 LoadingFinished
되지만 LoadFinished
다음에서 연결할 UIWebView
이벤트로 표시됩니다.
var webView = new UIWebView (...);
webView.LoadFinished += delegate { Console.WriteLine ("done!"); }
ModelAttribute
계약 API의 [Model]
형식 정의에 특성을 적용하면 런타임은 사용자가 클래스의 메서드를 덮어쓴 경우에만 클래스의 메서드에 호출을 표시하는 특수 코드를 생성합니다. 이 특성은 일반적으로 대리자 클래스를 래핑하는 모든 API에 Objective-C 적용됩니다.
런타임은 해당 프로토콜의 이름과 일치하는 클래스도 생성 Objective-C 합니다.
다음 두 가지 방법으로 클래스의 Objective-C 이름을 사용자 지정할 수 있습니다.
설정
AutoGeneratedName = true
:[Model (AutoGeneratedName = true)]
이렇게 하면 런타임에서 형식에 대한 고유한 이름을 생성합니다 Objective-C . 이름은 현재 어셈블리 이름과 모델 형식의 전체 이름을 기반으로 합니다(나중에 변경될 수 있음).
이름을 명시적으로 지정합니다.
[Model (Name = "CustomName")]
를 사용하는 AutoGeneratedName = true
것이 좋습니다. .NET에서는 이름이 항상 생성되며(위 2와 같이 명시적으로 지정되지 않은 경우) 속성이 AutoGeneratedName
더 이상 존재하지 않습니다.
NoDefaultValueAttribute
모델의 메서드가 기본 반환 값을 제공하지 않도록 지정합니다.
이 작업은 런타임 요청에 응답하여 false
Objective-C 지정된 선택기가 이 클래스에서 구현되는지 여부를 확인하여 런타임에서 작동 Objective-C 합니다.
[BaseType (typeof (NSObject))]
[Model][Protocol]
interface CameraDelegate {
[Export ("shouldDisplayPopup"), NoDefaultValue]
bool ShouldUploadToServer ();
}
참고 항목: [DefaultValue]
[DefaultValueFromArgument]
프로토콜
Objective-C 프로토콜 개념은 실제로 C#에 존재하지 않습니다. 프로토콜은 C# 인터페이스와 비슷하지만 프로토콜에 선언된 모든 메서드와 속성을 채택하는 클래스에서 구현해야 하는 것은 아니라는 점에서 다릅니다. 대신 일부 메서드 및 속성은 선택 사항입니다.
일부 프로토콜은 일반적으로 모델 클래스로 사용되며 특성을 사용하여 [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]
모든 정의는 실제로 프로토콜을 사용하는 방식을 크게 향상시키는 세 가지 지원 클래스를 생성합니다.
// 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#으로 인해 다른 기본 클래스가 필요하지만 인터페이스를 구현하려는 시나리오가 있습니다.
생성된 인터페이스 정의가 들어오는 위치입니다. 프로토콜에서 필요한 모든 메서드가 있는 인터페이스입니다. 이렇게 하면 프로토콜을 구현하려는 개발자가 인터페이스만 구현할 수 있습니다. 런타임은 프로토콜을 채택하는 형식으로 자동으로 등록합니다.
인터페이스는 필수 메서드만 나열하고 선택적 메서드를 노출합니다. 즉, 프로토콜을 채택하는 클래스는 필요한 메서드에 대한 전체 형식 검사를 받지만 선택적 프로토콜 메서드에 대해 약한 입력(수동으로 내보내기 특성 및 서명 일치 사용)에 의존해야 합니다.
프로토콜을 사용하는 API를 편리하게 사용할 수 있도록 바인딩 도구는 모든 선택적 메서드를 노출하는 확장 메서드 클래스도 생성합니다. 즉, 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
존재하지 않으므로 빈 인터페이스를 제공해야 하므로 위의 항목이 필요합니다.
프로토콜 생성 인터페이스 채택
프로토콜에 대해 생성된 인터페이스 중 하나를 구현할 때마다 다음과 같습니다.
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를 추가하면 자동 완성을 통해 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)
런타임에 두 동작 간에 약간의 동작 차이가 있습니다.
- 기본 클래스의 사용자(예: 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
속성에서 발생). 이 속성을 사용하여 getter를 데코레이트하고 맞춤 값을 사용할 수 있습니다. 일반적으로 API와 통합될 때 형식과 OpenTK.Matrix4
함께 OpenTK.Vector4
Objective-C 사용됩니다.
예시:
public interface GLKBaseEffect {
[Export ("constantColor")]
Vector4 ConstantColor { [Align (16)] get; set; }
}
AppearanceAttribute
특성은 [Appearance]
모양 관리자가 도입된 iOS 5로 제한됩니다.
[Appearance]
프레임워크에 참여하는 모든 메서드 또는 속성에 UIAppearance
특성을 적용할 수 있습니다. 이 특성이 클래스의 메서드 또는 속성에 적용되면 바인딩 생성기가 이 클래스의 모든 인스턴스 또는 특정 조건과 일치하는 인스턴스의 스타일을 지정하는 데 사용되는 강력한 형식의 모양 클래스를 만들도록 지시합니다.
예시:
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);
}
위의 코드는 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
컨트롤을 반환하거나 주 루프로 돌아갈 때까지만 드레이닝되는 추가 참조를 유지하지 않을 수 있습니다.
이 특성은 기본값NSAutoReleasePool
에 추가된 개체를 반환하는 무거운 속성(예UIImage.FromFile
: )에 적용됩니다. 이 특성이 없으면 스레드가 컨트롤을 주 루프로 반환하지 않는 한 이미지가 유지됩니다. Uf 스레드는 항상 살아 있고 작업을 기다리는 일종의 백그라운드 다운로더였으며 이미지는 결코 릴리스되지 않을 것입니다.
ForcedTypeAttribute
반환 [ForcedTypeAttribute]
된 관리되지 않는 개체가 바인딩 정의에 설명된 형식과 일치하지 않는 경우에도 관리되는 형식을 만드는 데 사용됩니다.
헤더에 설명된 형식이 네이티브 메서드의 반환된 형식과 일치하지 않는 경우에 유용합니다. 예를 들어 다음 정의를 NSURLSession
사용합니다Objective-C.
- (NSURLSessionDownloadTask *)downloadTaskWithRequest:(NSURLRequest *)request
인스턴스를 반환 NSURLSessionDownloadTask
할 것임을 명확하게 명시하지만, 슈퍼클래스이므로 변환할 수 없는 인스턴스를 반환NSURLSessionTask
합니다NSURLSessionDownloadTask
. 형식이 안전한 컨텍스트 InvalidCastException
에 있으므로 발생합니다.
헤더 설명을 준수하고 사용하지 않도록 InvalidCastException
하기 위해 사용됩니다 [ForcedTypeAttribute]
.
[BaseType (typeof (NSObject), Name="NSURLSession")]
interface NSUrlSession {
[Export ("downloadTaskWithRequest:")]
[return: ForcedType]
NSUrlSessionDownloadTask CreateDownloadTask (NSUrlRequest request);
}
[ForcedTypeAttribute]
또한 기본적으로 [ForcedType (owns: true)]
명명된 Owns
false
부울 값을 허용합니다. 소유 매개 변수는 Core Foundation 개체에 대한 소유권 정책을 따르는 데 사용됩니다.
매개 [ForcedTypeAttribute]
변수, 속성 및 반환 값에만 유효합니다.
BindAsAttribute
보다 [BindAsAttribute]
정확한 C# 형식으로 바인딩 NSNumber
NSValue
및 NSString
(열거형)을 허용합니다. 이 특성을 사용하여 네이티브 API를 통해 더 정확하고 정확한 .NET API를 만들 수 있습니다.
메서드(반환 값), 매개 변수 및 속성을 BindAs
데코레이트할 수 있습니다. 유일한 제한 사항은 멤버가 A 또는 [Model]
인터페이스 내에 [Protocol]
있지 않아야 한다는 것입니다.
예시:
[return: BindAs (typeof (bool?))]
[Export ("shouldDrawAt:")]
NSNumber ShouldDraw ([BindAs (typeof (CGRect))] NSValue rect);
다음을 출력합니다.
[Export ("shouldDrawAt:")]
bool? ShouldDraw (CGRect rect) { ... }
내부적으로 변환을 bool?
<>NSValue
<NSNumber
CGRect
>수행할 것입니다.
현재 지원되는 캡슐화 형식은 다음과 같습니다.
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
- 바이트
- 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
<NSString 상수에 [BindAs]
의해 지원되는 경우에만 ->NSString
변환을 처리합니다.
배열
[BindAs]
또한 지원되는 모든 형식의 배열을 지원합니다. 예를 들어 다음 API 정의를 사용할 수 있습니다.
[return: BindAs (typeof (CAScroll []))]
[Export ("getScrollModesAt:")]
NSString [] GetScrollModes ([BindAs (typeof (CGRect []))] NSValue [] rects);
다음을 출력합니다.
[Export ("getScrollModesAt:")]
CAScroll? [] GetScrollModes (CGRect [] rects) { ... }
매개 변수는 rects
각각 CGRect
에 대한 값이 포함된 NSValue
매개 변수로 NSArray
캡슐화되고, 그 대가로 반환 NSArray
되는 포함 값으로 생성된 배열 CAScroll?
을 NSStrings
가져옵니다.
BindAttribute
[Bind]
이 특성에는 메서드 또는 속성 선언에 적용할 때 두 가지 용도가 있고, 다른 하나는 속성의 개별 getter 또는 setter에 적용될 때 사용됩니다.
메서드 또는 속성에 사용할 경우 특성의 [Bind]
효과는 지정된 선택기를 호출하는 메서드를 생성하는 것입니다. 그러나 생성된 메서드는 특성으로 데코레이팅되지 않으므로 메서드 재정의 [Export]
에 참여할 수 없습니다. 일반적으로 확장 메서드를 구현하기 Objective-C 위한 특성과 [Target]
함께 사용됩니다.
예시:
public interface UIView {
[Bind ("drawAtPoint:withFont:")]
SizeF DrawString ([Target] string str, CGPoint point, UIFont font);
}
getter 또는 setter [Bind]
에서 사용되는 경우 특성은 속성에 대한 getter 및 setter Objective-C 선택기 이름을 생성할 때 코드 생성기에서 유추한 기본값을 변경하는 데 사용됩니다. 기본적으로 이름이 fooBar
있는 속성에 플래그를 지정하면 생성기에서 getter 및 setFooBar:
setter에 대한 내보내기를 생성 fooBar
합니다. 경우에 따라 Objective-C 이 규칙을 따르지 않는 경우가 있습니다. 일반적으로 getter 이름을 다음과 같이 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
사용하여 해당 메서드의 버전을 생성합니다. 콜백이 매개 변수를 사용하지 않는 경우 반환 값은 a Task
, 콜백이 매개 변수를 사용하는 경우 결과는 다음과 입니다 Task<T>
.
[Export ("upload:complete:")]
[Async]
void LoadFile (string file, NSAction complete)
다음은 이 비동기 메서드를 생성합니다.
Task LoadFileAsync (string file);
콜백이 여러 매개 변수를 사용하는 경우 모든 속성을 보유할 생성된 형식의 원하는 이름을 설정 ResultType
하거나 ResultTypeName
지정해야 합니다.
delegate void OnComplete (string [] files, nint byteCount);
[Export ("upload:complete:")]
[Async (ResultTypeName="FileLoading")]
void LoadFiles (string file, OnComplete complete)
다음은 이 비동기 메서드를 생성합니다. 여기서는 둘 다 액세스할 수 있는 FileLoading
속성과 byteCount
다음을 모두 files
포함합니다.
Task<FileLoading> LoadFile (string file);
콜백의 마지막 매개 변수가 NSError
있는 경우 생성된 Async
메서드는 값이 null이 아닌지 확인하고, 이 경우 생성된 비동기 메서드가 작업 예외를 설정합니다.
[Export ("upload:onComplete:")]
[Async]
void Upload (string file, Action<string,NSError> onComplete);
위의 비동기 메서드는 다음과 같습니다.
Task<string> UploadAsync (string file);
오류 발생 시 결과 태스크는 결과 NSError
작업을 래핑하는 예외로 NSErrorException
설정됩니다.
AsyncAttribute.ResultType
반환 개체에 대 한 값을 지정 하려면이 속성을 사용 합니다 Task
. 이 매개 변수는 기존 형식을 사용하므로 핵심 API 정의 중 하나에서 정의해야 합니다.
AsyncAttribute.ResultTypeName
반환 개체에 대 한 값을 지정 하려면이 속성을 사용 합니다 Task
. 이 매개 변수는 원하는 형식 이름의 이름을 사용합니다. 생성기는 콜백이 사용하는 각 매개 변수에 대해 하나씩 일련의 속성을 생성합니다.
AsyncAttribute.MethodName
생성된 비동기 메서드의 이름을 사용자 지정하려면 이 속성을 사용합니다. 기본값은 메서드의 이름을 사용하고 텍스트 "Async"를 추가하는 것입니다. 이 기본값을 변경하는 데 사용할 수 있습니다.
DesignatedInitializerAttribute
이 특성이 생성자에 적용되면 최종 플랫폼 어셈블리에서 동일하게 [DesignatedInitializer]
생성됩니다. 이는 IDE가 서브클래스에 사용해야 하는 생성자를 나타내는 데 도움이 됩니다.
이는 .의 __attribute__((objc_designated_initializer))
/clang 사용에 매핑Objective-C되어야 합니다.
DisableZeroCopyAttribute
이 특성은 문자열 매개 변수 또는 문자열 속성에 적용되며 코드 생성기에 이 매개 변수에 대해 0 복사 문자열 마샬링을 사용하지 않고 대신 C# 문자열에서 새 NSString 인스턴스를 만들도록 지시합니다.
이 특성은 명령줄 옵션을 사용하거나 어셈블리 수준 특성을 ZeroCopyStringsAttribute
설정하여 0 복사 문자열 마샬링을 사용하도록 생성기에 지시하는 --zero-copy
경우에만 문자열에 필요합니다.
속성이 속성 대신 copy
a retain
또는 assign
속성으로 선언되는 Objective-C 경우에 필요합니다. 일반적으로 개발자가 잘못 "최적화"한 타사 라이브러리에서 발생합니다. 일반적으로 retain
속성이 잘못 NSMutableString
되었거나 assign
NSString
사용자 파생 클래스 NSString
가 라이브러리 코드에 대한 지식 없이 문자열의 내용을 변경하여 애플리케이션을 미묘하게 손상할 수 있습니다. 일반적으로 이는 조기 최적화로 인해 발생합니다.
다음 두 가지 속성은 다음과 같습니다.Objective-C
@property(nonatomic,retain) NSString *name;
@property(nonatomic,assign) NSString *name2;
DisposeAttribute
클래스에 [DisposeAttribute]
적용할 때 클래스의 메서드 구현에 Dispose()
추가될 코드 조각을 제공합니다.
이 메서드는 Dispose
도구에서 bgen
자동으로 생성되므로 생성된 Dispose
메서드 구현에 일부 코드를 삽입하기 위해 특성을 사용해야 [Dispose]
합니다.
예시:
[BaseType (typeof (NSObject))]
[Dispose ("if (OpenConnections > 0) CloseAllConnections ();")]
interface DatabaseConnection {
}
ExportAttribute
이 [Export]
특성은 런타임에 노출될 메서드 또는 속성에 플래그를 Objective-C 지정하는 데 사용됩니다. 이 특성은 바인딩 도구와 실제 Xamarin.iOS 및 Xamarin.Mac 런타임 간에 공유됩니다. 메서드의 경우 매개 변수가 생성된 코드에 축자로 전달됩니다. 속성의 경우 getter 및 setter 내보내기는 기본 선언을 기반으로 생성됩니다(바인딩 도구의 동작을 변경하는 방법에 대한 자세한 내용은 섹션 참조 [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로 정의되거나 일부 API에서 사용되는 토큰이거나 Objective-C 값이 불투명하고 사용자 코드에서 있는 그대로 사용해야 하는 상수 값을 가져오는 데 필요합니다.
구문:
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
- 열거형
Setter는 NSString 상수에서 지원하는 열거형에 대해 지원되지 않지만 필요한 경우 수동으로 바인딩할 수 있습니다.
예시:
[Static]
interface CameraEffects {
[Field ("kCameraEffectsZoomFactorKey", "CameraLibrary")]
NSString ZoomFactorKey { get; }
}
InternalAttribute
이 특성은 [Internal]
메서드 또는 속성에 적용할 수 있으며 생성된 코드에 C# 키워드를 사용하여 생성된 코드 internal
에 플래그를 지정하여 생성된 어셈블리의 코드에만 액세스할 수 있도록 합니다. 이는 일반적으로 너무 낮은 수준의 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 예외를 catch하고 관리되는 예외로 마샬링하는 사용자 지정 트램폴린을 통과합니다.
현재는 몇 objc_msgSend
개의 서명만 지원되지만(바인딩을 사용하는 앱의 네이티브 연결이 누락된 xamarin__objc_msgSend 기호로 실패할 때 서명이 지원되지 않는지 확인) 요청 시 더 많은 서명을 추가할 수 있습니다.
NewAttribute
이 특성은 생성기가 선언 앞에 키워드를 생성 new
하도록 메서드 및 속성에 적용됩니다.
기본 클래스에 이미 있는 하위 클래스에 동일한 메서드 또는 속성 이름이 도입될 때 컴파일러 경고를 방지하는 데 사용됩니다.
NotificationAttribute
이 특성을 필드에 적용하여 생성기가 강력한 형식의 도우미 알림 클래스를 생성하도록 할 수 있습니다.
이 특성은 페이로드가 없는 알림에 대한 인수 없이 사용할 수 있으며, 일반적으로 이름이 "EventArgs"로 끝나는 API 정의에서 다른 인터페이스를 참조하는 인수를 지정할 System.Type
수 있습니다. 생성기는 인터페이스를 서브클래싱 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!");
});
또는 관찰할 특정 개체를 설정합니다. 이 메서드에 objectToObserve
전달 null
하면 다른 피어처럼 동작합니다.
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; }
}
위의 내용은 키를 ScreenXKey
사용하여 NSNotification.UserInfo 사전에서 데이터를 가져오고 ScreenY
각각 적절한 변환을 적용하는 속성과 ScreenYKey
함께 클래스 ScreenX
를 생성 MyScreenChangedEventArgs
합니다. 이 특성은 [ProbePresence]
생성기에서 UserInfo
값을 추출하는 대신 키가 설정되어 있는지 검색하는 데 사용됩니다. 이는 키의 존재가 값(일반적으로 부울 값의 경우)인 경우에 사용됩니다.
이렇게 하면 다음과 같은 코드를 작성할 수 있습니다.
var token = MyClass.NotificationsObserveScreenChanged ((notification) => {
Console.WriteLine ("The new screen dimensions are {0},{1}", notification.ScreenX, notification.ScreenY);
});
경우에 따라 사전에 전달된 값과 연결된 상수가 없습니다. Apple은 경우에 따라 공용 기호 상수를 사용하고 문자열 상수도 사용합니다. 기본적으로 제공된 EventArgs
클래스의 [Export]
특성은 런타임에 조회할 공용 기호로 지정된 이름을 사용합니다. 그렇지 않은 경우 대신 문자열 상수로 조회되어야 하는 경우 값을 Export 특성에 전달 ArgumentSemantic.Assign
합니다.
Xamarin.iOS 8.4의 새로운 기능
경우에 따라 알림은 인수 없이 수명을 시작하므로 인수 없이 사용할 [Notification]
수 있습니다. 그러나 경우에 따라 알림에 대한 매개 변수가 도입됩니다. 이 시나리오를 지원하기 위해 특성을 두 번 이상 적용할 수 있습니다.
바인딩을 개발하고 기존 사용자 코드의 호환성이 손상되지 않도록 하려면 다음에서 기존 알림을 설정합니다.
interface MyClass {
[Notification]
[Field ("MyClassScreenChangedNotification")]
NSString ScreenChangedNotification { get; }
}
다음과 같이 알림 특성을 두 번 나열하는 버전으로:
interface MyClass {
[Notification]
[Notification (typeof (MyScreenChangedEventArgs)]
[Field ("MyClassScreenChangedNotification")]
NSString ScreenChangedNotification { get; }
}
NullAllowedAttribute
속성에 적용되면 속성에 값을 null
할당할 수 있도록 플래그를 지정합니다. 참조 형식에 대해서만 유효합니다.
메서드 서명의 매개 변수에 적용되는 경우 지정된 매개 변수가 null일 수 있으며 값을 전달 null
하기 위해 검사를 수행해서는 안 됨을 나타냅니다.
참조 형식에 이 특성이 없으면 바인딩 도구는 할당된 값을 전달 Objective-C 하기 전에 할당되는 값에 대한 검사를 생성하고 할당된 null
값이 있는지 여부를 throw ArgumentNullException
하는 검사를 생성합니다.
예시:
// In properties
[NullAllowed]
UIImage IconFile { get; set; }
// In methods
void SetImage ([NullAllowed] UIImage image, State forState);
OverrideAttribute
이 특성을 사용하여 바인딩 생성기에 이 특정 메서드에 대한 바인딩에 키워드로 플래그를 override
지정하도록 지시합니다.
PreSnippetAttribute
이 특성을 사용하여 입력 매개 변수의 유효성을 검사한 후 코드가 호출 Objective-C되기 전에 삽입할 코드를 삽입할 수 있습니다.
예시:
[Export ("demo")]
[PreSnippet ("var old = ViewController;")]
void Demo ();
PrologueSnippetAttribute
이 특성을 사용하여 생성된 메서드에서 매개 변수의 유효성을 검사하기 전에 삽입할 코드를 삽입할 수 있습니다.
예시:
[Export ("demo")]
[Prologue ("Trace.Entry ();")]
void Demo ();
PostGetAttribute
이 클래스에서 지정된 속성을 호출하여 값을 가져오도록 바인딩 생성기에 지시합니다.
이 속성은 일반적으로 참조 개체 그래프를 유지 하는 개체를 가리키는 캐시를 새로 고치는 데 사용 합니다. 일반적으로 추가/제거와 같은 작업이 있는 코드에 표시됩니다. 이 메서드는 요소를 추가하거나 제거한 후 내부 캐시를 업데이트하여 실제로 사용 중인 개체에 대한 관리되는 참조를 유지하도록 하는 데 사용됩니다. 바인딩 도구는 지정된 바인딩의 모든 참조 개체에 대한 지원 필드를 생성하기 때문에 가능합니다.
예시:
[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; }
}
이 경우 Dependencies
개체에서 NSOperation
종속성을 추가하거나 제거한 후 속성이 호출되어 실제 로드된 개체를 나타내는 그래프가 있는지 확인하여 메모리 누수와 메모리 손상을 모두 방지합니다.
PostSnippetAttribute
이 특성을 사용하여 코드가 기본 메서드를 호출한 후 삽입할 일부 C# 소스 코드를 삽입할 수 있습니다.Objective-C
예시:
[Export ("demo")]
[PostSnippet ("if (old != null) old.DemoComplete ();")]
void Demo ();
ProxyAttribute
이 특성은 값을 반환하여 프록시 개체로 플래그를 지정하는 데 적용됩니다. 일부 Objective-C API는 사용자 바인딩과 구별할 수 없는 프록시 개체를 반환합니다. 이 특성의 효과는 개체에 개체로 플래그를 지정하는 DirectBinding
것입니다. Xamarin.Mac의 시나리오에서는 이 버그에 대한 설명을 볼 수 있습니다.
ReleaseAttribute(Xamarin.iOS 6.0)
반환 형식에 적용하여 생성기가 개체를 반환하기 전에 개체를 호출 Release
해야 함을 나타낼 수 있습니다. 이는 메서드가 보존된 개체를 제공하는 경우에만 필요합니다(가장 일반적인 시나리오인 자동 릴리스된 개체와는 반대).
예시:
[Export ("getAndRetainObject")]
[return: Release ()]
NSObject GetAndRetainObject ();
또한 이 특성은 생성된 코드로 전파되므로 Xamarin.iOS 런타임은 이러한 함수에서 반환할 Objective-C 때 개체를 유지해야 한다는 것을 알 수 있습니다.
SealedAttribute
생성된 메서드에 sealed로 플래그를 지정하도록 생성기에 지시합니다. 이 특성을 지정하지 않으면 기본값은 가상 메서드(가상 메서드, 추상 메서드 또는 다른 특성 사용 방법에 따라 재정의)를 생성하는 것입니다.
StaticAttribute
특성이 [Static]
메서드 또는 속성에 적용되면 정적 메서드 또는 속성이 생성됩니다. 이 특성을 지정하지 않으면 생성기에서 인스턴스 메서드 또는 속성을 생성합니다.
TransientAttribute
이 특성을 사용하여 iOS에서 일시적으로 생성되지만 수명이 길지 않은 개체의 값이 일시적인 속성에 플래그를 지정합니다. 이 특성이 속성에 적용되면 생성기는 이 속성에 대한 지원 필드를 만들지 않습니다. 즉, 관리되는 클래스가 개체에 대한 참조를 유지하지 않습니다.
WrapAttribute
Xamarin.iOS/Xamarin.Mac 바인딩 [Wrap]
의 디자인에서 특성은 강력한 형식의 개체로 약한 형식의 개체를 래핑하는 데 사용됩니다. 이는 주로 Objective-C 형식 id
또는 NSObject
형식으로 선언되는 대리자 개체에서 발생합니다. Xamarin.iOS 및 Xamarin.Mac에서 사용하는 규칙은 해당 대리자 또는 데이터 원본을 형식 NSObject
으로 노출하는 것이며, "Weak" + 노출되는 이름을 사용하여 명명됩니다. 속성 id delegate
Objective-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#의 형식 시스템을 활용하며 재정의 키워드를 사용하여 의도를 선언하고, 사용자에 대한 바인딩에서 작업을 수행했으므로 메서드를 [Export]
수동으로 데코레이트할 필요가 없습니다.
// This is the strong case,
class MyDelegate : DemoDelegate {
override void Demo DoDemo () {}
}
var strongDemo = new Demo ();
demo.Delegate = new MyDelegate ();
이 특성의 [Wrap]
또 다른 용도는 강력한 형식의 메서드 버전을 지원하는 것입니다. 예시:
[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]
데코레이팅된 [Category]
형식 내의 메서드에 특성을 적용하는 경우 확장 메서드가 생성되기 때문에 첫 번째 인수로 포함 This
해야 합니다. 예시:
[Wrap ("Write (This, image, options?.Dictionary, out error)")]
bool Write (CIImage image, CIImageRepresentationOptions options, out NSError error);
기본적으로 생성된 [Wrap]
멤버는 선택적 isVirtual
매개 변수로 설정할 true
수 있는 멤버가 virtual
필요한 경우 기본값이 아닙니다virtual
.
[BaseType (typeof (NSObject))]
interface FooExplorer {
[Export ("fooWithContentsOfURL:")]
void FromUrl (NSUrl url);
[Wrap ("FromUrl (NSUrl.FromString (url))", isVirtual: true)]
void FromUrl (string url);
}
[Wrap]
속성 getter 및 setter에서 직접 사용할 수도 있습니다.
이렇게 하면 모든 권한을 갖고 필요에 따라 코드를 조정할 수 있습니다.
예를 들어 스마트 열거형을 사용하는 다음 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에서 한 번에 하나의 개체만 표시할 수 있기 때문에 API는 SetDisplay (SomeObject)
이 특성을 사용합니다. 둘 이상의 개체(예: Stack 유사 API)를 추적해야 하는 경우 이 특성을 사용합니다 [RetainList]
.
구문:
public class RetainAttribute {
public RetainAttribute ();
public RetainAttribute (string wrapName);
public string WrapName { get; }
}
TransientAttribute
이 특성은 매개 변수에 적용되며 C#으로 Objective-C 전환할 때만 사용됩니다. 이러한 전환 중에는 다양한 Objective-CNSObject
매개 변수가 개체의 관리되는 표현으로 래핑됩니다.
런타임은 네이티브 개체에 대한 참조를 사용하고 개체에 대한 마지막 관리되는 참조가 사라질 때까지 참조를 유지하고 GC를 실행할 기회가 있습니다.
경우에 따라 C# 런타임에서 네이티브 개체에 대한 참조를 유지하지 않는 것이 중요합니다. 이 문제는 기본 네이티브 코드가 매개 변수의 수명 주기에 특별한 동작을 연결한 경우에 발생합니다. 예를 들어 매개 변수의 소멸자는 일부 정리 작업을 수행하거나 일부 귀중한 리소스를 삭제합니다.
이 특성은 덮어쓴 메서드에서 다시 돌아갈 때 가능하면 개체를 삭제하려는 런타임에 Objective-C 알릴 수 있습니다.
규칙은 간단합니다. 런타임이 네이티브 개체에서 새 관리 표현을 만들어야 하는 경우 함수의 끝에 네이티브 개체의 보존 수가 삭제되고 관리되는 개체의 Handle 속성이 지워집니다. 즉, 관리되는 개체에 대한 참조를 유지하면 해당 참조가 쓸모 없게 됩니다(메서드를 호출하면 예외가 throw됨).
전달된 개체가 만들어지지 않았거나 개체의 미해결 관리 표현이 이미 있는 경우 강제 삭제가 수행되지 않습니다.
Attributes 속성
NotImplementedAttribute
이 특성은 getter가 있는 속성이 기본 클래스에 도입되고 변경 가능한 서브클래스가 setter를 도입하는 관용구를 지원하는 Objective-C 데 사용됩니다.
C#은 이 모델을 지원하지 않으므로 기본 클래스에는 setter와 getter가 모두 있어야 하며 하위 클래스는 OverrideAttribute를 사용할 수 있습니다.
이 특성은 속성 setter에서만 사용 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
}
위의 바인딩 정의에서 생성기는 자체를 만들고 열거형 값과 NSString
상수 간의 양방향 변환 메서드를 포함하는 정적 형식을 만듭니 enum
*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
이 특성으로 하나의 열거형 값을 데코레이트할 수 있습니다. 열거형 값을 알 수 없는 경우 반환되는 상수가 됩니다.
위의 예제에서 다음을 수행합니다.
var x = (NSRunLoopMode) 99;
Call (x.GetConstant ()); // NSDefaultRunLoopMode will be used
열거형 값이 데코레이트되지 않으면 throw NotSupportedException
됩니다.
ErrorDomainAttribute
오류 코드는 열거형 값으로 바인딩됩니다. 일반적으로 오류 도메인이 있으며 어떤 도메인이 적용되는지(또는 하나라도 존재하는지) 찾기가 항상 쉬운 것은 아닙니다.
이 특성을 사용하여 오류 도메인을 열거형 자체와 연결할 수 있습니다.
예시:
[Native]
[ErrorDomain ("AVKitErrorDomain")]
public enum AVKitError : nint {
None = 0,
Unknown = -1000,
PictureInPictureStartFailed = -1001
}
그런 다음 확장 메서드 GetDomain
를 호출하여 오류의 도메인 상수 값을 가져올 수 있습니다.
FieldAttribute
형식 내 상수에 사용되는 것과 동일한 [Field]
특성입니다. 열거형 내에서 값을 특정 상수로 매핑하는 데 사용할 수도 있습니다.
null
값을 사용하여 상수를 지정하는 경우 null
NSString
반환할 열거형 값을 지정할 수 있습니다.
위의 예제에서 다음을 수행합니다.
var constant = NSRunLoopMode.NewInWatchOS3; // will be null in watchOS 2.x
Call (NSRunLoopModeExtensions.GetValue (constant)); // will return 1000
값이 없 null
으면 throw ArgumentNullException
됩니다.
전역 특성
전역 특성은 같은 [LinkWithAttribute]
특성 한정자를 사용하여 [assembly:]
적용되거나 가용성 특성과 같은 어디서나 사용할 수 있습니다.
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
사용되는지 여부를 결정하는 데 사용됩니다. 지금은 항상 사실이어야 합니다.
LinkWithAttribute.Frameworks
바인딩되는 라이브러리에 프레임워크(및 제외 Foundation
UIKit
)에 대한 하드 요구 사항이 있는 경우 필요한 플랫폼 프레임워크의 공백으로 구분된 목록을 포함하는 문자열로 속성을 설정 Frameworks
해야 합니다. 예를 들어 필요한 CoreGraphics
라이브러리를 바인딩하는 CoreText
경우 속성을 "CoreGraphics CoreText"
.로 설정합니다Frameworks
.
LinkWithAttribute.IsCxx
C 컴파일러인 기본값 대신 C++ 컴파일러를 사용하여 결과 실행 파일을 컴파일해야 하는 경우 이 속성을 true로 설정합니다. 바인딩하는 라이브러리가 C++로 작성된 경우 사용합니다.
LinkWithAttribute.LibraryName
번들로 묶을 관리되지 않는 라이브러리의 이름입니다. 확장명 ".a"가 있는 파일이며 여러 플랫폼(예: 시뮬레이터의 경우 ARM 및 x86)에 대한 개체 코드를 포함할 수 있습니다.
이전 버전의 Xamarin.iOS는 라이브러리가 지원하는 플랫폼을 확인하기 위해 속성을 확인 LinkTarget
했지만, 이제 자동으로 검색되고 LinkTarget
속성이 무시됩니다.
LinkWithAttribute.LinkerFlags
이 문자열은 네이 LinkerFlags
티브 라이브러리를 애플리케이션에 연결할 때 필요한 추가 링커 플래그를 지정하는 바인딩 작성자를 위한 방법을 제공합니다.
예를 들어 네이티브 라이브러리에 libxml2 및 zlib가 필요한 경우 문자열"-lxml2 -lz"
을 LinkerFlags
.로 설정합니다.
LinkWithAttribute.LinkTarget
이전 버전의 Xamarin.iOS는 라이브러리가 지원하는 플랫폼을 확인하기 위해 속성을 확인 LinkTarget
했지만, 이제 자동으로 검색되고 LinkTarget
속성이 무시됩니다.
LinkWithAttribute.NeedsGccExceptionHandling
연결하는 라이브러리에 GCC 예외 처리 라이브러리(gcc_eh)가 필요한 경우 이 속성을 true로 설정합니다.
LinkWithAttribute.SmartLink
SmartLink
Xamarin.iOS에서 필요한지 여부를 ForceLoad
확인할 수 있도록 속성을 true로 설정해야 합니다.
LinkWithAttribute.WeakFrameworks
속성은 WeakFrameworks
링크 타임 -weak_framework
에 Frameworks
나열된 각 프레임워크에 대해 지정자가 gcc에 전달된다는 점을 제외하고 속성과 동일한 방식으로 작동합니다.
WeakFrameworks
를 사용하면 라이브러리와 애플리케이션이 플랫폼 프레임워크에 대해 약하게 연결할 수 있으므로 사용 가능한 경우 필요에 따라 사용할 수 있지만 라이브러리가 최신 버전의 iOS에 추가 기능을 추가하려는 경우 유용한 종속성을 사용하지 않습니다. 약한 연결에 대한 자세한 내용은 약한 연결에 대한 Apple의 설명서를 참조하세요.
약한 연결 Frameworks
에 대한 좋은 후보는 계정, CoreBluetooth
, NewsstandKit
CoreImage
GLKit
및 Twitter
iOS 5에서만 사용할 수 있기 때문에 다음과 같습니다.
AdviceAttribute
이 특성을 사용하여 개발자가 사용하기에 더 편리할 수 있는 다른 API에 대한 힌트를 제공합니다. 예를 들어 강력한 형식의 API 버전을 제공하는 경우 약한 형식의 특성에서 이 특성을 사용하여 개발자를 더 나은 API로 안내할 수 있습니다.
이 특성의 정보는 설명서에 나와 있으며 개선 방법에 대한 사용자 제안을 제공하기 위해 도구를 개발할 수 있습니다.
RequiresSuperAttribute
이 특성은 메서드를 재정의하려면 기본(재정의 [Advice]
된) 메서드 에 대한 호출이 필요하다 는 것을 개발자에게 암시하는 데 사용할 수 있는 특성의 특수한 하위 클래스입니다.
이에 해당합니다. clang
__attribute__((objc_requires_super))
ZeroCopyStringsAttribute
Xamarin.iOS 5.4 이상에서만 사용할 수 있습니다.
이 특성은 이 특정 라이브러리(적용 [assembly:]
된 경우) 또는 형식에 대한 바인딩이 빠른 제로 복사 문자열 마샬링을 사용하도록 생성기에 지시합니다. 이 특성은 명령줄 옵션을 --zero-copy
생성기에 전달하는 것과 같습니다.
문자열에 대해 0 복사를 사용하는 경우 생성기는 새 NSString
개체를 만들지 않고 C# 문자열에서 문자열 Objective-C 로 데이터를 복사하지 않고 사용하는 문자열과 동일한 C# 문자열 Objective-C 을 효과적으로 사용합니다. 제로 복사본 문자열을 사용하는 유일한 단점은 래핑하는 문자열 속성이 플래그가 지정 retain
copy
[DisableZeroCopy]
되거나 특성 집합이 있는지 확인해야 한다는 것입니다. 이는 0개 복사 문자열에 대한 핸들이 스택에 할당되고 함수 반환 시 유효하지 않으므로 필요합니다.
예시:
[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에서 파생되는 인터페이스와 동일한 이름의 클래스를 생성하고 인터페이스에 정의된 각 속성을 사전에 대한 강력한 형식의 getter 및 setter로 바꿉니다.
이렇게 하면 기존 NSDictionary
클래스에서 인스턴스화할 수 있거나 새로 만들어진 클래스가 자동으로 생성됩니다.
이 특성은 사전의 요소에 액세스하는 데 사용되는 키를 포함하는 클래스의 이름인 하나의 매개 변수를 사용합니다. 기본적으로 특성이 있는 인터페이스의 각 속성은 접미사가 "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
합니다.
다른 키를 사용하려는 경우 속성에서 내보내기 특성을 사용할 수 있습니다. 예를 들면 다음과 같습니다.
[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# Array NSObject |
NSArray |
열거형의 C# Array |
NSArray NSNumber 값 포함 |