목표에 대 한 .NET 포함 모범 사례-C.NET Embedding best practices for Objective-C

이는 초안 이며 현재 도구에서 지원 되는 기능과 동기화 되지 않을 수 있습니다.This is a draft and might not be in-sync with the features presently supported by the tool. 이 문서는 별도로 진화 하 고 최종적으로 최종 도구와 일치 하는 것이 좋습니다. 즉, 즉각적인 해결 방법이 아니라 장기적인 모범 사례를 제안 합니다.We hope that this document will evolve separately and eventually match the final tool, i.e. we'll suggest long term best approaches - not immediate workarounds.

이 문서의 많은 부분은 지원 되는 다른 언어에도 적용 됩니다.A large part of this document also applies to other supported languages. 그러나 제공 된 모든 예제는 C# 및 목표-C에 있습니다.However all provided examples are in C# and Objective-C.

관리 코드의 하위 집합 노출Exposing a subset of the managed code

생성 된 네이티브 라이브러리/프레임 워크에는 노출 된 각 관리 되는 Api를 호출 하는 목표 C 코드가 포함 됩니다.The generated native library/framework contains Objective-C code to call each of the managed APIs that is exposed. 표시 되는 API (공용)를 늘리면 기본 붙이기 라이브러리가 커집니다.The more API you surface (make public) then larger the native glue library will become.

네이티브 개발자에 게 필요한 Api만 노출 하는 다른 작은 어셈블리를 만드는 것이 좋을 수 있습니다.It might be a good idea to create a different, smaller assembly, to expose only the required APIs to the native developer. 이 외관을 사용 하면 표시 유형, 명명, 오류 검사 등을 더 자세히 제어할 수 있습니다. 생성 된 코드의입니다.That facade will also allow you more control over the visibility, naming, error checking... of the generated code.

Chunkier API 노출Exposing a chunkier API

네이티브에서 관리 (및 뒤로)로 전환 하기 위해 비용을 지불 해야 합니다.There is a price to pay to transition from native to managed (and back). 따라서 네이티브 개발자에 게 번잡 api 대신 청크 를 노출 하는 것이 좋습니다 (예:).As such, it's better to expose chunky instead of chatty APIs to the native developers, e.g.

번잡Chatty

public class Person {
  public string FirstName { get; set; }
  public string LastName { get; set; }
}
// this requires 3 calls / transitions to initialize the instance
Person *p = [[Person alloc] init];
p.firstName = @"Sebastien";
p.lastName = @"Pouliot";

청크Chunky

public class Person {
  public Person (string firstName, string lastName) {}
}
// a single call / transition will perform better
Person *p = [[Person alloc] initWithFirstName:@"Sebastien" lastName:@"Pouliot"];

전환 횟수가 작을수록 성능이 향상 됩니다.Since the number of transitions is smaller the performance will be better. 또한 더 적은 수의 코드를 생성 해야 하므로 더 작은 네이티브 라이브러리도 생성 됩니다.It also requires less code to be generated, so this will produce a smaller native library as well.

명명Naming

이름을 지정 하는 작업은 컴퓨터 과학에서 가장 어려운 두 가지 문제, 다른 사용자가 캐시를 무효화 하는 문제 및 1 ~ 2 개 오류 중 하나입니다.Naming things is one of two hardest problems in computer science, the others being cache invalidation and off-by-1 errors. .NET 포함을 통해 이름을 지정할 수 있지만 이름을 지정할 수 있습니다.Hopefully .NET Embedding can shield you from all but naming.

유형Types

목적-C는 네임 스페이스를 지원 하지 않습니다.Objective-C does not support namespaces. 일반적으로 해당 형식에는 프레임 워크를 나타내는 UIKit의 보기에 대 한 UIView 같이 2 (Apple의 경우) 또는 3 (타사) 문자 접두사가 접두사로 붙습니다.In general, its types are prefixed with a 2 (for Apple) or 3 (for 3rd parties) character prefix, like UIView for UIKit's View, which denotes the framework.

.NET 형식의 경우 중복 되거나 혼동 되는 이름을 도입할 수 있으므로 네임 스페이스를 건너뛸 수 없습니다.For .NET types skipping the namespace is not possible as it can introduce duplicated, or confusing, names. 이렇게 하면 기존 .NET 형식이 매우 깁니다. 예를 들면 다음과 같은 경우입니다.This makes existing .NET types very long, e.g.

namespace Xamarin.Xml.Configuration {
  public class Reader {}
}

다음과 같이 사용 됩니다.would be used like:

id reader = [[Xamarin_Xml_Configuration_Reader alloc] init];

그러나 형식을 다음과 같이 다시 표시할 수 있습니다.However you can re-expose the type as:

public class XAMXmlConfigReader : Xamarin.Xml.Configuration.Reader {}

다음을 사용 하 여 더 쉽게 이해할 수 있습니다.making it more Objective-C friendly to use, e.g.:

id reader = [[XAMXmlConfigReader alloc] init];

메서드Methods

좋은 .NET 이름도 목표-C API에 적합 하지 않을 수 있습니다.Even good .NET names might not be ideal for an Objective-C API.

목표에 대 한 명명 규칙은 .NET과 다릅니다 (파스칼식 대/소문자가 아닌 카멜식 대/소문자, 자세한 정보).Naming conventions in Objective-C are different than .NET (camel case instead of pascal case, more verbose). Cocoa의 코딩 지침을 읽어 보세요.Please read the coding guidelines for Cocoa.

목표-C 개발자 관점에서 Get 접두사가 있는 메서드는 인스턴스를 소유 하 고 있지 않음을 의미 합니다 (예: get 규칙).From an Objective-C developer's point of view, a method with a Get prefix implies you do not own the instance, i.e. the get rule.

이 명명 규칙은 .NET GC 세계와 일치 하지 않습니다. Create 접두사가 있는 .NET 메서드는 .NET에서 동일 하 게 동작 합니다.This naming rule has no match in the .NET GC world; a .NET method with a Create prefix will behave identically in .NET. 그러나 목표-C 개발자의 경우에는 일반적으로 반환 되는 인스턴스 (예: create rule)를 소유 하 고 있음을 의미 합니다.However, for Objective-C developers, it normally means you own the returned instance, i.e. the create rule.

예외Exceptions

.NET에서 예외를 광범위 하 게 사용 하 여 오류를 보고 하는 것이 일반적입니다.It's quite common in .NET to use exceptions extensively to report errors. 그러나 속도가 느리고 목표에서 동일 하지는 않습니다.However, they are slow and not quite identical in Objective-C. 가능 하면 항상 목표-C 개발자 로부터 숨겨야 합니다.Whenever possible you should hide them from the Objective-C developer.

예를 들어, .NET Try 패턴은 목표-C 코드에서 훨씬 더 쉽게 사용할 수 있습니다.For example, the .NET Try pattern will be much easier to consume from Objective-C code:

public int Parse (string number)
{
  return Int32.Parse (number);
}

위험과versus

public bool TryParse (string number, out int value)
{
  return Int32.TryParse (number, out value);
}

init* 내의 예외Exceptions inside init*

.NET에서 생성자는 성공 하 고 올바른_인스턴스를 반환_하거나 예외를 throw 해야 합니다.In .NET a constructor must either succeed and return a (hopefully) valid instance or throw an exception.

이와 대조적으로, 목표는 인스턴스를 만들 수 없을 때 init* nil를 반환할 수 있도록 합니다.In contrast, Objective-C allows init* to return nil when an instance cannot be created. 이 패턴은 대부분의 Apple 프레임 워크에서 사용 되는 일반적인 패턴입니다.This is a common, but not general, pattern used in many of Apple's frameworks. 다른 경우에는 assert 발생 하 고 현재 프로세스를 중단할 수 있습니다.In some other cases an assert can happen (and kill the current process).

생성자는 생성 된 init* 메서드에 대해 동일한 return nil 패턴을 따릅니다.The generator follow the same return nil pattern for generated init* methods. 관리 되는 예외가 throw 되 면 NSLog를 사용 하 여 출력 되 고 nil 호출자에 게 반환 됩니다.If a managed exception is thrown, then it will be printed (using NSLog) and nil will be returned to the caller.

연산자Operators

목적-C에서는 연산자가 처럼 C# 오버 로드 될 수 없으므로 클래스 선택기로 변환 됩니다.Objective-C does not allow operators to be overloaded as C# does, so these are converted to class selectors.

"친숙 한" 명명 된 메서드는 발견 될 때 연산자 오버 로드에 대 한 우선 순위로 생성 되며 API를 더 쉽게 사용할 수 있습니다."Friendly" named methods are generated in preference to the operator overloads when found, and can produce an easier to consume API.

및/또는 != == 연산자를 재정의 하는 클래스는 표준 Equals (Object) 메서드도 재정의 해야 합니다.Classes that override the operators == and\or != should override the standard Equals (Object) method as well.