2017-02-15 3 views
1

먼저, Xamarin이 "링커"라고 부르는 것은 일반적으로 "데드 코드 리무버"에 관한 것입니다. 그것은 호출 할 수없는 코드가 컴파일 된 응용 프로그램에 들어가는 것을 방지해야합니다.Xamarin 링커는 모든 생성자를 제거하지만 인스턴스 메서드는 그대로 유지합니까?

내 앱에 유형이 있습니다.

private static void LogMemberInfo(Type type) { 
    int constructorCount = GetConstructorCount(type); 
    MyLoggingMethod(constructorCount, "Constructors"); 
    MemberInfo[] members = type.GetMembers(); 
    List<string> willLog = new List<string>(); 
    foreach(MemberInfo member in members) { 
    if (member.DeclaringType == type) { 
     willLog.Add(member.Name); 
    } 
    } 
    willLog.Sort(); 
    foreach (string str in willLog) { 
    MyLoggingMethod.LogLine(str); 
    } 
} 

위의 출력은 다음과 같습니다 : 나는 그것의 인스턴스 멤버를 참조하는 반사를 사용하는 경우 그러나, 나는 많은 참조

private static int GetConstructorCount(Type type) { 
    ConstructorInfo[] constructors = type.GetConstructors(); 
    return constructors.Count(); 
} 

: 나는 그것의 생성자를 얻기 위해 반사를 사용할 때, 나는 제로 생성자를 참조

0 Constructors 
lots of surviving members, including instance members 

이 유형은 유형이 다른 많은 유형의 게이트웨이이기 때문에 문제가됩니다. 모든 생성자를 없애면 모든 인스턴스 멤버가 사라질 것입니다. 그들은하지 않습니다.

이것은 링커의 버그입니까? 아니면 인스턴스 멤버를 없애고 싶지 않은 이유가 있습니까?

캐스팅을 통해 유형의 멤버에 액세스합니다. 아마도 이것이 문제일까요?

public class MySuperclass { 
    public static MySuperclass Instance {get; set;} 
} 

public MyClass: MySuperclass { 
    public static SomeMethod() { 
    MySuperclass object = MySuperclass.Instance; 
    MyClass castObject = object as MyClass; // castObject will always be null, as no constructors survived the linking process. But maybe the linker doesn't realize that? 
    if (castObject!=null) { 
     castObject.InstanceMethod(); 
    } 
    } 
} 

업데이트 : 모든 캐스트를 제거해도 문제가 해결되지 않았습니다. 많은 곳에서 수퍼 클래스 객체의 가상 멤버를 호출하고 있습니다. 그게 내 다음 추측이지만, 그게 문제라면, 고치기가 더러워 질거야.

+0

는 사용자 정의 링크의 설명을 지정하려 했 자 마린 문서? https://developer.xamarin.com/guides/cross-platform/advanced/custom_linking/ –

+0

아니요, 제가 거기에 가야 할 수도 있지만 먼저 무슨 일이 일어나고 있는지 알고 싶습니다. –

+0

링커는 매우 간단하고 강력합니다. Json 직렬화, 크로스 어셈블리 클래스/멤버 제거 등을 처리하기위한 커스텀 단계를 작성했습니다.코드를보고 테스트 케이스에서 실행하면 도움이 될 수 있습니다. https://github.com/mono/linker/tree/master/linker – SushiHangover

답변

0

필자의 경우 적어도 하나의 정적 메서드를 호출하면 많은 인스턴스 멤버가 보존됩니다. 말 그대로이 시도 : 유형이 링커에 의해 제거하기 일단

public class MyType() { 
    public static bool DummyBool() { 
    return true; 
    } 
    // instance members here 
} 

을, 나는) (MyType.DummyBool에 대한 호출에 넣어. 이로 인해 많은 인스턴스 멤버가 보존되었습니다.

모든 사람에게 해당되는 것은 아닙니다. 그러나 그것은 나를위한 경우입니다.

그들이 호출되지 않은 경우에도, 정적 클래스가 시작할 때 초기화됩니다 어떤 특성을 가지고 있으며, 전체 클래스가 보존되는 경우, 그 특성이 보존되어 있다는 것입니다 조심하는 또 다른 음험 한 것 :

링커에서 제거 된 클래스의 코드가 제거되지 않는 다른 클래스를 발생시키는 경우도 하나 이상 있습니다. 나는 이것이 버그라고 생각한다. 그러나 나의 예는 오히려 복잡하고 간단한 재현을위한 나의 시도는 실패했다.

0

Preserve 속성을 사용해 보셨습니까? 링커가 장식 코드 "최적화"하지 않습니다 자세한 내용은

[Xamarin.iOS.Foundation.Preserve] 

를 참조 here

+0

내 문제는 반대입니다. 제거하려는 코드를 보관하고 있습니다. –

관련 문제