Monotouch: как оптимизировать производительность для ручной загрузки NIB - PullRequest
4 голосов
/ 12 марта 2012

Я использую scrollview для отображения многостраничного представления, которое имеет более 10 страниц. (Scrollview.PageEnabled = истина)

И каждая страница в просмотре прокрутки имеет около 6 вложенных представлений (с именем: ABCUI), каждое из которых загружается из пера:

    this.scrollview.DecelerationEnded+= scrollView_DecelerationEnded(...);

    public void LoadSubView(int nPageNo)
    {
       if (this.PageLoaded(nPageNo))
          return;

       for (int i=0;i<6;i++)    
       {
         ABCViewController abcUI=MonoTouch.Foundation.NSBundle.MainBundle.LoadNib ("ABCUI", this, null); //XIB file size: 20K

         abcui.SetTitle(...);  
         abcui.SetXXXX(...);
         abcui.frame = ..  pageFrame.X += this.ScrollView.Frame.Width+nPage*...;    

         this.scrollview.addsubview(abcUI.view,...);
       }
    }


    public void scrollView_DecelerationEnded (object sender, EventArgs e)
    {
        int nPageNo=(int)Math.Ceiling((this.ScrollView.ContentOffset.X+1)/this.ScrollView.Frame.Width);

        this.LoadSubView(nPageNo +1);
        this.LoadSubView(nPageNo - 1);  
    }

public void Button1Clicked(object sender, EventArgs e)
{
   this.ClearViewsInScrollView();
   this.LoadSubView(1); 
}

Когда пользователь запускает нажатие кнопки 1, он загружает первую страницу в просмотр прокрутки (только 1 страница за один раз, но 1 страница имеет 6 вложенных просмотров), а когда пользователь прокручивает просмотр прокрутки, он загружает следующую страницу.

Но при загрузке первой страницы или переключении страницы в режиме прокрутки потребуется много времени, поэтому пользователь должен ждать:

  1. ipad1: около 1000 мс
  2. iPad2: около 600 мс
  3. в симуляторе: 100 мс;

как оптимизировать производительность (уменьшить до 300мс / ipad1)?

1 Ответ

5 голосов
/ 12 марта 2012

Очень хороший вопрос и отличное время, так как я работал над чем-то вроде этого в последние несколько дней.

Теперь я не уверен, что это решение даст вам загрузку <300 мс, однако теоретически этобыстрее. </p>

(Вы увидите термины «XIB» и «NIB». Я имею в виду одно и то же. В конце концов, NIB - это «скомпилированный» XIB.)

Ключ ко всему состоит в том, чтобы предотвратить загрузку каждого файла XIB несколько раз.Для этого нет никаких оснований, поскольку вам (нам) в основном это нужно - это экземпляров из объектов в XIB, а не сами XIB, занимающие память.

К счастью,iOS SDK предоставляет класс UINib, который может делать то, что мы хотим.С помощью этого класса мы можем создавать несколько экземпляров содержимого XIB без необходимости каждый раз загружать сам XIB, только один раз в «начало».

Вот как это сделать:

Во-первых, создайте объект UINib для каждого требуемого файла XIB.

// Loads a NIB file without instantiating its contents.
// Simplified here, but to have access to a NIB for the whole lifecycle of the app,
// create a singleton somewhere.
static UINib abcuiNib = UINib.FromName("ABCUI", NSBundle.MainBundle);

Во-вторых, после загрузки NIB в память вы теперь можете получать объекты из него.

abcuiNib.InstantiateWithOwneroptions(this, new NSDictionary());

Обратите внимание на параметр this.Поскольку это контроллер представления, который вы хотите загрузить, указанная выше строка должна находиться где-то в начале жизненного цикла объекта, например, в конструкторе:

public partial class ABCViewController : UIViewController
{

    public ABCViewController()
    {

        // The first parameter is needed to set an owner (File's Owner) for the objects
        // that will be instantiated.
        // The second parameter is for various options. It does not accept null in MonoTouch,
        // but you can just pass an empty NSDictionary.
        // If you have all your outlets correctly set up, the following line is all 
        // that is needed.
        abcuiNib.InstantiateWithOwneroptions(this, new NSDictionary());

    }

    // We don't need the following, as it will load the XIB every time
    //public ABCViewController() : base("ABCUI", null) {}

// view controller implementation

}

Имейте в виду, я не проверял вышеизложенное, так какДо сих пор я тестировал его с различными объектами в XIB.Если (и когда) я буду использовать его с UIViewControllers в XIB, это направление, в котором я буду двигаться. Я также подготовлю статью с более подробными результатами и информацией в свое время.

Также обратите внимание, чтоприменяются те же "правила", например,вам все равно придется разблокировать все выходы в переопределении ViewDidUnload.

Если после этого вы не обнаружите каких-либо улучшений в производительности, я думаю, вам нужно будет перепроектировать ваши XIB.Apple предполагает, что лучше иметь несколько XIB с несколькими объектами в каждом, вместо нескольких XIB, заполненных объектами.

Полезное чтение: Документы Apple по управлению NIB

...