Search code examples
iosgrand-central-dispatchrubymotion

Is it possible to make a background thread run faster?


I am using RubyMotion and have a calendar implemented using CKCalendarView and I have the following code highlighting days on which events occur.

The following method is called from layoutSubviews

def calendarDidLayoutSubviews(calendar)
  _events_array = []
  if self.events
    self.events.reverse.each do |ev|
      mdy = ev.date.month_date_year
      _events_array <<  mdy unless _events_array.include?(mdy)
    end
  end

  Dispatch::Queue.main.async do
    today = NSDate.date.month_date_year

    if calendar.dateButtons && calendar.dateButtons.length > 0
      calendar.dateButtons.each do |db|
        db.backgroundColor = "f4f2ee".to_color
        if db.date && db.date >= calendar.minimumDate && db.date <= calendar.maximumDate
          if _events_array && _events_array.length > 0
            db.setTitleColor("c7c3bb".to_color, forState:UIControlStateNormal)
            db.backgroundColor = "f4f2ee".to_color
            if _events_array.include?(db.date.month_date_year)
              db.setTitleColor(UIColor.blackColor, forState:UIControlStateNormal)
              db.backgroundColor = "9ebf6c".to_color
              _events_array.delete(db.date.month_date_year)
            end
          end
        end
        if db.date && db.date.month_date_year == today
          if calendar.minimumDate <= db.date && calendar.maximumDate >= db.date
            db.setTitleColor(UIColor.blackColor, forState:UIControlStateNormal)
          else
            db.setTitleColor("f4f2ee".to_color, forState:UIControlStateNormal)
          end
        end
      end
    end
  end
end

As it is, this freezes the UI for a .5 - 1.5s when drawing. If I move it in to a background thread, it takes 4 or 5 times as long to draw, but doesn't freeze the UI.

Question: Is there a way to give the background thread a higher priority, or a way to incrementally draw and highlight the dateButtons so that it doesn't look like nothing is happening in the half dozen seconds it takes to draw(when not in the main thread)?


Solution

  • The method I posted was getting called in the main thread, so I switched it to be called in a background thread, and then called the main thread for all drawing operations inside my loop.

    def calendarDidLayoutSubviews(calendar)
       _events_array = []
      if self.events
        self.events.reverse.each do |ev|
          mdy = ev.date.month_date_year
          _events_array <<  mdy unless _events_array.include?(mdy)
        end
      end
    
      today = NSDate.date.month_date_year
    
      if calendar.dateButtons && calendar.dateButtons.length > 0
        calendar.dateButtons.each do |db|
          Dispatch::Queue.main.async do
            db.backgroundColor = "f4f2ee".to_color
          end
          if db.date && db.date >= calendar.minimumDate && db.date <= calendar.maximumDate
            if _events_array && _events_array.length > 0
              Dispatch::Queue.main.async do
                db.setTitleColor("c7c3bb".to_color, forState:UIControlStateNormal)
                db.backgroundColor = "f4f2ee".to_color
              end
              if _events_array.include?(db.date.month_date_year)
                Dispatch::Queue.main.async do
                  db.setTitleColor(UIColor.blackColor, forState:UIControlStateNormal)
                  db.backgroundColor = "9ebf6c".to_color
                end
                _events_array.delete(db.date.month_date_year)
              end
            end
          end
          if db.date && db.date.month_date_year == today
            if calendar.minimumDate <= db.date && calendar.maximumDate >= db.date
              Dispatch::Queue.main.async do
                db.setTitleColor(UIColor.blackColor, forState:UIControlStateNormal)
              end
            else
              Dispatch::Queue.main.async do
                db.setTitleColor("f4f2ee".to_color, forState:UIControlStateNormal)
              end
            end
          end
        end
      end
    end