Monotouch:如何优化手动加载NIB的性能

Blu*_*Sky 4 scrollview xamarin.ios

我使用scrollview来显示多页视图,它有10页以上.(scrollview.PageEnabled = TRUE)

scrollview中的每个页面都有大约6个子视图(名为:ABCUI),每个子视图都是从nib加载的:

    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); 
}
Run Code Online (Sandbox Code Playgroud)

当用户触发button1单击时,它会将第一页加载到scrollview中(一次只有1页,但是1页有6个子视图),当用户滚动滚动视图时,它将加载下一页.

但是在scrollview中加载第一页或切换页面需要很长时间,因此用户必须等待:

  1. ipad1:大约1000ms
  2. iPad2:约600ms
  3. 在模拟器中:100ms;

如何优化性能(减少到300ms/ipad1)?

Dim*_*kos 5

非常好的问题和出色的时间,因为我过去几天一直在做这样的事情.

现在,我不确定这个解决方案是否会让你<300毫秒加载,但理论上它更快.

(你会看到"XIB"和"NIB"两个术语.我指的是同样的事情.毕竟,NIB是一个"编译过的"XIB.)

整个过程的关键是防止多次加载每个XIB文件.没有理由为它,因为你(我们)基本上都是从它需要的是实例从XIBs的对象,而不是本身占用内存XIBs.

幸运的是,iOS SDK提供了UINib可以做我们想要的类.使用此类,我们可以创建XIB内容的多个实例,而无需每次都加载XIB本身,只需在"开始"中加载一次.

这是怎么做的:

首先,为您想要的每个XIB文件创建一个UINib对象.

// 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);
Run Code Online (Sandbox Code Playgroud)

其次,在将NIB加载到内存后,您现在可以从中获取对象.

abcuiNib.InstantiateWithOwneroptions(this, new NSDictionary());
Run Code Online (Sandbox Code Playgroud)

注意"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

}
Run Code Online (Sandbox Code Playgroud)

请注意,我还没有对上面的内容进行过测试,因为到目前为止,我已经在XIB中测试了各种单个对象.如果(和何时)我在XIB中使用UIViewControllers,这就是我将要进入的方向.我还将准备一篇文章,在适当的时候提供更深入的调查结果和信息.

另请注意,相同的"规则"适用,例如.您仍然必须释放ViewDidUnload覆盖中的所有插座.

如果在此之后,您没有发现任何性能方面的改进,我认为您需要重新设计您的XIB.Apple建议最好让多个XIB在每个XIB中包含很少的对象,而不是几个包含对象的XIB.

有用的阅读:关于NIB管理的Apple文档