Когда я должен сохранять ссылку на мой контроллер или представление, а когда нет? Смотрите примеры - PullRequest
2 голосов
/ 15 сентября 2011

Есть два сценария, о которых я постоянно удивляюсь, когда использую Monotouch.Они имеют дело с требованием сохранить ссылку на UIViewController или UIView.

Пример один (я нашел это в базе данных ошибок MT).Он реализует MKMapViewDelegate, и представление, возвращаемое из GetViewForAnnotation, будет собирать мусор, если не будет сохранена управляемая ссылка:

class MapViewDelegate : MKMapViewDelegate
{
    public override MKAnnotationView GetViewForAnnotation (MKMapView mapView, NSObject annotation)
    {
        var myAnnotation = annotation as MyAnnotation;
        var view = new MKPinAnnotationView (myAnnotation, "myannotation");
        var button = UIButton.FromType (UIButtonType.DetailDisclosure);
        view.RightCalloutAccessoryView = button;

        // I have had this fail as "invalid selector", and also a SIGSEGV crash
        button.TouchDown += delegate {
            Console.WriteLine("I was touched!");
        };

        annotationView = view;

        return annotationView;
    }
}

Пример два: если я использую PresentModalViewController(), мне кажется, чтовыжить без удержания управляемой ссылки:

ModalSettingsController oSettingsController = new ModalSettingsController ( );
this.PresentModalViewController(oSettingsController, true);

Я никогда не сталкивался с пустой ссылкой, SIGSEGV или чем-то подобным в этом случае.Похоже, что в этом случае «что-то» сохраняет ссылку.

Проблема, с которой я столкнулся, заключается в следующем: если бы я использовал чистую среду C # без мира ObjC, код из примера 1 работал бы без проблем;представление было создано и присвоено чему-то другому, то есть ссылка существует.Но так как представление, возвращенное в первом примере, восходит к ObjC и не имеет управляемой ссылки, GC удалит управляемую версию.Это немного озадачивает меня.Как я могу выяснить, в каких случаях я должен сохранять ссылку, а когда нет?Нужно ли мне просматривать документы Apple и видеть, сохраняет ли получатель вид или контроллер?

1 Ответ

1 голос
/ 15 сентября 2011

Должен ли я просматривать документы Apple и видеть, сохраняет ли получатель вид или контроллер?

Нет. В целом (> 98% API) MonoTouch будет обрабатывать необходимые ссылки, чтобы ваш управляемый объект работал столько времени, сколько требуется. Это может быть сделано, потому что вы вызываете некоторый управляемый (C #) код из вашего приложения. Э.Г.

 this.PresentModalViewController(oSettingsController, true);

Это позволяет управляемому методу PresentModalViewController сохранять ссылку (при необходимости) на oSettingsController столько времени, сколько необходимо.

Так в чем проблема с некоторыми API? Проблема в том, кто вызывает API. Э.Г.

public override MKAnnotationView GetViewForAnnotation (MKMapView mapView, NSObject annotation)

Если бы это называлось формой C #, то это не было бы проблемой, т. Е. Ваше утверждение относительно pure C # в основном правильно.

Однако он вызывается из ObjectiveC , поскольку мы переопределяем метод из унаследованного нативного типа. Таким образом, в этом случае управляемый объект view не имеет (управляемой) ссылки (если только вы не добавите ее, как в примере # 1) после возврата метода. Но собственный вызывающий объект будет сохранять собственный часть представления , поэтому все будет работать ... пока ваше приложение не попытается вернуться в управляемый код.

Так как управляемый узел, например, view , было собрано, тогда все, что удалось внутри него, будет собрано тоже (например, кнопка ). Вот почему сбой часто происходит в событиях, например, в делегате, назначенном вами TouchDown .

При этом мы работаем над решением, которое охватит этот случай и в будущих версиях MonoTouch. Добавьте себя на c.c. отчет об ошибке , если вы хотите получать уведомления о прогрессе.

...