2013-05-27 3 views
5

В настоящее время я пишу программу, которая поможет мне управлять сложными установками освещения. Идея заключается в том, что я предлагаю программе запустить пресет, тогда приложение имеет три варианта (в зависимости от типа предустановок)Предварительная обработка цикла в Objective-C

1) огни идут в одну позицию (так что только одна группа данных, отправляемых при запуске пресета) 2) свет следует математическое уравнение (например: синусовый с таймером, чтобы сделать гладкие круги) 3) огни реагировать на поток данных (контроллер миди ех)

Так что я решил пойти с объектом I вызовите AppBrain, которые получают данные от контроллеров и шаблонов, но также могут отправлять обработанные данные в фары.

Теперь я пришел из не-родного программирования, и у меня есть вопросы доверия, связанные с работой с большим количеством обработки, событий и времени; а также проблемы с пониманием 100% логики какао.

Это где начинается собственно вопрос, извините

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

Чтобы объяснить более глубоко, вот как я бы сделал это в Javascript (дерьмовый псевдокод, конечно)

var lightsFunctions = {}; 

function prepareTemplate(theTemplate){ 
    //Let's assume here the template is just an array, and I won't show all the processing 

    switch(theTemplate.typeOfTemplate){ 
     case "simpledata": 
      sendAllDataTooLights(); // Simple here 
      break; 

     case "periodic": 


       for(light in theTemplate.lights){ 

        switch(light.typeOfEquation){ 
         case "sin": 
          lightsFunctions[light.id] = doTheSinus; // doTheSinus being an existing function 
          break; 

         case "cos": 

          ... 
        } 
       } 


       function onFrame(){ 
        for(light in lightsFunctions){ 
         lightsFunctions[light](); 
        } 
       } 

       var theTimer = setTimeout(onFrame, theTemplate.delay); 

       break; 

      case "controller": 

       //do the same pre-processing without the timer, to know which function to execute for which light 

       break; 

    } 


    } 

} 

Итак, моя идея состоит в том, чтобы сохранить функцию обработки мне нужно в NSArray, так что я не нужно тестировать на каждом кадре тип и потерять некоторое время/процессор.

Я не знаю, ясно ли я, или если моя идея возможна/хороший путь. Я в основном ищу алгоритмические идеи, и если у вас есть код, который может направить меня в хорошем направлении ... (я знаю о PerformSelector, но я не знаю, является ли это наилучшим вариантом для этой ситуации.

Спасибо;

I_

+4

Просто создайте его без оптимизации в первую очередь. 100 * 100 'sin()' вызовов в секунду - ничего, работающая на native. IPhone 5 может выполнять ~ 6 миллионов 'sin()' вычислений в секунду. – mvds

+0

Сказал вам, я очень боюсь! Но я не могу перестать думать о том, что произойдет, если все огни упадут перед 10 000 человек ... Я в настоящее время использую ARC для спасения своей спины, но я снова доверяю проблеме с автоматизированным материалом ... – Moustach

+0

@Mostach Как побочный элемент, вы все равно должны знать о своей памяти при работе с ARC. У ARC есть «странные» правила (точнее, управление памятью больше компилируется с использованием ARC), и отчасти это то, что я бы посоветовал вам изучить и изначально использовать MRC. Не ожидайте, что ARC станет волшебством! :) Хороший первый вопрос, кстати, +1. –

ответ

4

Прежде всего, не тратить время на оптимизацию, что вы не знаете, это проблема с производительностью 100 итераций типа ничего в родном мире, даже на более слабом мобильном телефоне. CPU

Теперь, к вашей проблеме. Я полагаю, вы пишете какую-то конфигурацию/DSL, чтобы указать последовательности управления светом. Один из способов делать это, чтобы хранить blocks в вашем NSArray. Блок является эквивалентом объекта функции в JavaScript. Так, например:

typedef void (^LightFunction)(void); 

- (NSArray*) parseProgram ... { 
    NSMutableArray* result = [NSMutableArray array]; 
    if(...) { 
     LightFunction simpledata = ^{ sendDataToLights(); }; 
     [result addObject:simpleData]; 
    } else if(...) { 
     Light* light = [self getSomeLight:...]; 
     LightFunction periodic = ^{ 
      // Note how you can access the local scope of the outside function. 
      // Make sure you use automatic reference counting for this. 
      [light doSomethingWithParam:someParam]; 
     }; 
     [result addObject:periodic]; 
    } 
    return result; 
} 
... 
NSArray* program = [self parseProgram:...]; 

// To run your program 
for(LightFunction func in program) { 
    func(); 
} 
+1

Блок ** не является ** эквивалентным функциональному объекту, не ошибитесь. Это объект, но это гораздо больше, чем функция.Это сумасшедшие вещи с управлением памятью (сохранение циклов), имеет странные способы вызова (вызов блока «nil» приводит к SIGABRT) и многие другие причуды. Это скорее традиционный указатель функции, чем объект функции. –

+0

Хм, это действительно здорово! Мой вопрос будет тогда, можно ли сохранить его как свойство объекта, так что я мог бы сделать что-то вроде '[light prepareWithAction: ...]; .... [обновление освещения]; ' Обновление, являющееся блоком, конечно? – Moustach

+0

Да, вы можете получить доступ к местным пользователям за пределами области действия блока. Он работает так же, как работает JavaScript. См. Обновленный пример. – Krumelur