Xamarin iOS App зависает при использовании AssociatedObject для установки AutomationId для UIAlertController - objc_getAssociatedObject - PullRequest
0 голосов
/ 24 мая 2018

Мы пытаемся установить AutomationId для UIAlertController, используя расширения в Xamarin.iOS.Но приложение неустойчиво падает при var valuePtr = objc_getAssociatedObject(alertAction.Handle, DescriptiveName.Handle); при методе GetAccessibilityIdentifier.Также не знаю, почему происходит сбой.

Ниже приведен пример кода:

public static class UIAlertControllerExtension
    {
        public static void ApplyAccessibilityIdentifiers(this UIAlertController alertController)
        {
            foreach (var action in alertController.Actions)
            {
                var lable = action.ValueForKey((NSString)"__representer");
                var view = lable as UIView;
                view.AccessibilityIdentifier = action.GetAccessibilityIdentifier();
            }
        }
    }

    public static class UIAlertActionExtension
    {

        private static readonly NSString DescriptiveName = new NSString("AccesabilityIdentifier" + nameof(UIAlertActionExtension));

        #region "Extension properties"

        enum AssociationPolicy
        {
            Assign = 0,
            RetainNonAtomic = 1,
            CopyNonAtomic = 3,
            Retain = 01401,
            Copy = 01403,
        }

        [DllImport("/usr/lib/libobjc.dylib")]
        static extern void objc_setAssociatedObject(
            IntPtr pointer, IntPtr key,
            IntPtr value, AssociationPolicy policy);

        [DllImport("/usr/lib/libobjc.dylib")]
        static extern IntPtr objc_getAssociatedObject(
            IntPtr pointer, IntPtr key);


        #endregion

        public static void SetAccessibilityIdentifier(this UIAlertAction alertAction, NSString accessabilityIdentifier)
        {
            objc_setAssociatedObject (alertAction.Handle, DescriptiveName.Handle, accessabilityIdentifier.Handle, AssociationPolicy.Retain);
        }

        public static NSString GetAccessibilityIdentifier(this UIAlertAction alertAction)
        {
            try
            {
                var valuePtr = objc_getAssociatedObject(alertAction.Handle, DescriptiveName.Handle); // App is crashed at this line.
                if (valuePtr != IntPtr.Zero)
                {
                    var result = ObjCRuntime.Runtime.GetNSObject(valuePtr);
                    if (result != null)
                        return (NSString)result;
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }

            //var value = ObjCRuntime.Runtime.GetNSObject(valuePtr) as NSString;
            return new NSString("");
        }

    }

Создан контроллер предупреждений и задан AutomationId с использованием вышеуказанного метода расширения, как показано ниже.

private void ShowAlert()
{
    var alertController = UIAlertController.Create("Title", "Message", UIAlertControllerStyle.Alert);

    var action = UIAlertAction.Create("Ok", UIAlertActionStyle.Default, delegate
                {

                    // Do Somthing

                });

   action.SetAccessibilityIdentifier((NSString) accessibilityIdentifier);

   alertController.AddAction(action);

   this.PresentViewController(alertController, true, () => { alertController.ApplyAccessibilityIdentifiers(); });
}

Мы вызываем этот метод нажатием кнопки на контроллере представления, и он работает нормально несколько раз.Но приложение выходит из строя, когда показывает предупреждение 3-й или 4-й раз.

Пожалуйста, помогите мне решить эту проблему.

Заранее спасибо.

1 Ответ

0 голосов
/ 25 мая 2018

AssociationPolicy.Retain может сделать это свойство неожиданным, так что ваше приложение вылетает.Вы можете изменить его на AssociationPolicy.RetainNonAtomic.NonAtomic сделает ваше приложение работоспособным и быстрым.

Если вы просто хотите сохранить строку и использовать ее позже.Почему бы не попробовать NSUserDefaults или статический экземпляр?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...