Правильная утилизация NSTimer в Monotouch

#iphone #ios #ipad #xamarin.ios

#iPhone #iOS #iPad #xamarin.ios

Вопрос:

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

Если я сделаю следующее:

 NSTimer.CreateScheduledTimer(10, delegate {
    Console.WriteLine("Timer fired!");
    // other non-trivial code here
});
  

Как только это сработает, будет ли это автоматически очищено GC Mono? Или было бы лучше создать ссылку на этот таймер ( NSTimer timer = NSTimer.CreateScheduledTimer() ), а затем утилизировать его самостоятельно?

Применимо ли это к другим объектам, которые могут быть созданы аналогичным образом?

Ответ №1:

Ваш пример кода, вероятно, является правильным решением. GC очистится через некоторое время после срабатывания таймера. Единственная причина, по которой вы можете захотеть сохранить ссылку на таймер, — это если вы захотите отменить таймер в какой-то момент.

Ответ №2:

Я использую этот маленький помощник. Хорошо то, что он может использоваться во всех производных классах NSObject и помогает при преобразовании кода из ObjC, поскольку это практически тот же вызов.

 namespace MonoTouch.Foundation.Extensions
{
    public static class CoreFoundationExtensions
    {
        /// <summary>
        /// Performs the selector.
        /// </summary>
        /// <param name='obj'>
        /// Object.
        /// </param>
        /// <param name='action'>
        /// Action.
        /// </param>
        /// <param name='delay'>
        /// Delay.
        /// </param>
        public static void PerformSelector (this NSObject obj, NSAction action, float delay)
        {
            int d = (int)(1000 * delay);

            var thread = new Thread(new ThreadStart ( () => {
                using(var pool = new NSAutoreleasePool())
                    {
                        Thread.Sleep (d); 
                        action.Invoke ();
                    }
             }));           

            thread.IsBackground = true;
            thread.Start();
        }

        /// <summary>
        /// Performs the selector.
        /// </summary>
        /// <param name='obj'>
        /// Object.
        /// </param>
        /// <param name='action'>
        /// Action.
        /// </param>
        public static void PerformSelector (this NSObject obj, NSAction action)
        {
            PerformSelector (obj, action, 0.001f);
        }
    }
}