zoukankan      html  css  js  c++  java
  • 使用NSOperation为你的app加速

    app store中的很多应用程序非常的笨重,他们有好的界面,但操作性很差,比如说当程序从网上或本地载入数据的时候,界面被冻结了,用户只能等程序完全载入数据之后才能进行操作。
    当打开一个应用程序时,iphone会产生一个包含main方法的线程,所用程序中的界面都是运行在这个线程之中的(table views, tab bars, alerts…),有时候我们会用数据填充这些view,现在问题是如何有效的载入数据,并且用户还能自如的操作程序。
    下面要说方法的并不是要在用户载入数据的时候在界面上提示“loading”的信息,虽然这种方式在有些时候是可以被接受的,但当数据在main线程之外被载入是并不是最有效的方式。
    先看一下要演示的程序:


    这个程序将从网络上下载10,000条数据,并填入到UITableView中,现面的代码将首先演示一种错误的方式:
    错误 (源码 )

     
    @implementation
    
     RootViewController
    @synthesize
    
     array
    
    ;
     
    -
    
     (
    
    void
    
    )
    
    viewDidLoad {
    
    
    [
    
    super viewDidLoad]
    
    ;
     
    /* Adding the button */
    
    
    self
    
    .navigationItem.rightBarButtonItem =
    
     [
    
    [
    
    UIBarButtonItem alloc
    
    ]
    
     initWithTitle
    
    :
    
    @"Load"
    
    
    style
    
    :
    
    UIBarButtonItemStyleDone
    target
    
    :
    
    self
    
    
    action
    
    :
    
    @selector
    
    (
    
    loadData)
    
    ]
    
    ;
     
    /* Initialize our array */
    
    
    NSMutableArray
    
     *
    
    _array =
    
     [
    
    [
    
    NSMutableArray
    
     alloc
    
    ]
    
     initWithCapacity
    
    :
    
    10000
    
    ]
    
    ;
    self
    
    .array
    
     =
    
     _array;
    [
    
    _array release
    
    ]
    
    ;
    }
    
    
     
    // Fires when the user presses the load button
    
    
    -
    
     (
    
    void
    
    )
    
     loadData {
    
    
     
    /* Grab web data */
    
    
    NSURL
    
     *
    
    dataURL =
    
     [
    
    NSURL
    
     URLWithString
    
    :
    
    @"http://icodeblog.com/samples/nsoperation/data.plist"
    
    ]
    
    ;
     
    NSArray
    
     *
    
    tmp_array =
    
     [
    
    NSArray
    
     arrayWithContentsOfURL
    
    :
    
    dataURL]
    
    ;
     
    /* Populate our array with the web data */
    
    
    for
    
    (
    
    NSString
    
     *
    
    str in
    
     tmp_array)
    
     {
    
    
    [
    
    self
    
    .array
    
     addObject
    
    :
    
    str]
    
    ;
    }
    
    
     
    /* reload the table */
    
    
    [
    
    self
    
    .tableView
    
     reloadData
    
    ]
    
    ;
    }
    
    
     
    #pragma mark Table view methods
    
    
     
    -
    
     (
    
    NSInteger)
    
    numberOfSectionsInTableView:
    
    (
    
    UITableView *
    
    )
    
    tableView
    
     {
    
    
    return
    
     1
    
    ;
    }
    
    
     
    -
    
     (
    
    NSInteger)
    
    tableView
    
    :
    
    (
    
    UITableView *
    
    )
    
    tableView
    
     numberOfRowsInSection:
    
    (
    
    NSInteger)
    
    section {
    
    
    return
    
     [
    
    self
    
    .array
    
     count
    
    ]
    
    ;
    }
    
    
     
    -
    
     (
    
    UITableViewCell *
    
    )
    
    tableView
    
    :
    
    (
    
    UITableView *
    
    )
    
    tableView
    
     cellForRowAtIndexPath:
    
    (
    
    NSIndexPath
    
     *
    
    )
    
    indexPath {
    
    
     
    static
    
     NSString
    
     *
    
    CellIdentifier =
    
     @"Cell"
    
    ;
     
    UITableViewCell *
    
    cell
    
     =
    
     [
    
    tableView
    
     dequeueReusableCellWithIdentifier:
    
    CellIdentifier]
    
    ;
    if
    
     (
    
    cell
    
     ==
    
     nil
    
    )
    
     {
    
    
    cell
    
     =
    
     [
    
    [
    
    [
    
    UITableViewCell alloc
    
    ]
    
     initWithStyle:
    
    UITableViewCellStyleDefault
    reuseIdentifier:
    
    CellIdentifier]
    
     autorelease
    
    ]
    
    ;
    }
    
    
     
    /* Display the text of the array */
    
    
    [
    
    cell
    
    .textLabel setText:
    
    [
    
    self
    
    .array
    
     objectAtIndex
    
    :
    
    indexPath.row
    
    ]
    
    ]
    
    ;
     
    return
    
     cell
    
    ;
    }
    
    
     
    -
    
     (
    
    void
    
    )
    
    dealloc
    
     {
    
    
    [
    
    super dealloc
    
    ]
    
    ;
    [
    
    array
    
     release
    
    ]
    
    ;
    }
    
    
     
    @end
    
    
     


    当点击“load”按钮时程序会被冻结,直到将数据完全下载并填入Tableview,在这期间用户不能做任何的事情。
    在给出解决方式之前先来看一下NSOperationQueue和NSOperation:

    The NSOperation and NSOperationQueue classes  alleviate much of the pain of multi-threading, allowing you to simply  define your tasks, set any dependencies that exist, and fire them off.  Each task, or operation , is represented by an instance  of an NSOperation class; the NSOperationQueueclass  takes care of starting the operations, ensuring that they are run in  the appropriate order, and accounting for any priorities that have been  set.

    下面要做的是建立NSOperationQueue和NSOperations。NSOperationQueue会建立一个线程,每个加入到线程operation会有序的执行。
    下面是使用NSOperationQueue的过程:

    1. 建立一个NSOperationQueue的对象
    2. 建立一个NSOperation的对象
    3. 将operation加入到NSOperationQueue中
    4. release掉operation

    使用NSOperation有几种,现在介绍最简单的一种NSInvocationOperation,NSInvocationOperation是NSOperation的子类,允许运行在operation中的targer和selector。  下面是执行NSInvocationOperation的一个例子:

     
    NSOperationQueue
    
     *
    
    queue =
    
     [
    
    NSOperationQueue
    
     new
    
    ]
    
    ;
     
    NSInvocationOperation
    
     *
    
    operation
    
     =
    
     [
    
    [
    
    NSInvocationOperation
    
     alloc
    
    ]
    
     initWithTarget
    
    :
    
    self
    
    
    selector
    
    :
    
    @selector
    
    (
    
    methodToCall)
    
    
    object
    
    :
    
    objectToPassToMethod]
    
    ;
     
    [
    
    queue addOperation:
    
    operation
    
    ]
    
    ;
    [
    
    operation
    
     release
    
    ]
    
    ;
     
     


    下面是我们用正确的方式实现的程序:
    正确的方式(下载源码 )

     
    @implementation
    
     RootViewController
    @synthesize
    
     array
    
    ;
     
    -
    
     (
    
    void
    
    )
    
    viewDidLoad {
    
    
        [
    
    super viewDidLoad]
    
    ;
     
        self
    
    .navigationItem.rightBarButtonItem =
    
     [
    
    [
    
    UIBarButtonItem alloc
    
    ]
    
     initWithTitle
    
    :
    
    @"Load"
    
    
           style
    
    :
    
    UIBarButtonItemStyleDone
           target
    
    :
    
    self
    
    
           action
    
    :
    
    @selector
    
    (
    
    loadData)
    
    ]
    
    ;
     
        NSMutableArray
    
     *
    
    _array =
    
     [
    
    [
    
    NSMutableArray
    
     alloc
    
    ]
    
     initWithCapacity
    
    :
    
    10000
    
    ]
    
    ;
        self
    
    .array
    
     =
    
     _array;
        [
    
    _array release
    
    ]
    
    ;
    }
    
    
     
    -
    
     (
    
    void
    
    )
    
     loadData {
    
    
     
        /* Operation Queue init (autorelease) */
    
    
        NSOperationQueue
    
     *
    
    queue =
    
     [
    
    NSOperationQueue
    
     new
    
    ]
    
    ;
     
        /* Create our NSInvocationOperation to call loadDataWithOperation, passing in nil */
    
    
        NSInvocationOperation
    
     *
    
    operation
    
     =
    
     [
    
    [
    
    NSInvocationOperation
    
     alloc
    
    ]
    
     initWithTarget
    
    :
    
    self
    
    
            selector
    
    :
    
    @selector
    
    (
    
    loadDataWithOperation)
    
    
            object
    
    :
    
    nil
    
    ]
    
    ;
     
        /* Add the operation to the queue */
    
    
        [
    
    queue addOperation:
    
    operation
    
    ]
    
    ;
        [
    
    operation
    
     release
    
    ]
    
    ;
    }
    
    
     
    -
    
     (
    
    void
    
    )
    
     loadDataWithOperation {
    
    
        NSURL
    
     *
    
    dataURL =
    
     [
    
    NSURL
    
     URLWithString
    
    :
    
    @"http://icodeblog.com/samples/nsoperation/data.plist"
    
    ]
    
    ;
     
        NSArray
    
     *
    
    tmp_array =
    
     [
    
    NSArray
    
     arrayWithContentsOfURL
    
    :
    
    dataURL]
    
    ;
     
        for
    
    (
    
    NSString
    
     *
    
    str in
    
     tmp_array)
    
     {
    
    
            [
    
    self
    
    .array
    
     addObject
    
    :
    
    str]
    
    ;
        }
    
    
     
        [
    
    self
    
    .tableView
    
     reloadData
    
    ]
    
    ;
    }
    
    
     
    #pragma mark Table view methods
    
    
     
    -
    
     (
    
    NSInteger)
    
    numberOfSectionsInTableView:
    
    (
    
    UITableView *
    
    )
    
    tableView
    
     {
    
    
        return
    
     1
    
    ;
    }
    
    
     
    -
    
     (
    
    NSInteger)
    
    tableView
    
    :
    
    (
    
    UITableView *
    
    )
    
    tableView
    
     numberOfRowsInSection:
    
    (
    
    NSInteger)
    
    section {
    
    
        return
    
     [
    
    self
    
    .array
    
     count
    
    ]
    
    ;
    }
    
    
     
    -
    
     (
    
    UITableViewCell *
    
    )
    
    tableView
    
    :
    
    (
    
    UITableView *
    
    )
    
    tableView
    
     cellForRowAtIndexPath:
    
    (
    
    NSIndexPath
    
     *
    
    )
    
    indexPath {
    
    
     
        static
    
     NSString
    
     *
    
    CellIdentifier =
    
     @"Cell"
    
    ;
     
        UITableViewCell *
    
    cell
    
     =
    
     [
    
    tableView
    
     dequeueReusableCellWithIdentifier:
    
    CellIdentifier]
    
    ;
        if
    
     (
    
    cell
    
     ==
    
     nil
    
    )
    
     {
    
    
            cell
    
     =
    
     [
    
    [
    
    [
    
    UITableViewCell alloc
    
    ]
    
     initWithStyle:
    
    UITableViewCellStyleDefault reuseIdentifier:
    
    CellIdentifier]
    
     autorelease
    
    ]
    
    ;
        }
    
    
     
        [
    
    cell
    
    .textLabel setText:
    
    [
    
    self
    
    .array
    
     objectAtIndex
    
    :
    
    indexPath.row
    
    ]
    
    ]
    
    ;
     
        return
    
     cell
    
    ;
    }
    
    
     
    -
    
     (
    
    void
    
    )
    
    dealloc
    
     {
    
    
        [
    
    super dealloc
    
    ]
    
    ;
        [
    
    array
    
     release
    
    ]
    
    ;
    }
    
    
     


    再次运行程序,当点击“load”按钮时界面是否还被“冻结”呢,程序并没有增加很多的代码,但确大大的提高了用户体验。

  • 相关阅读:
    jmeter----Linux上安装与使用
    Jmeter----客户端内存配置修改(Windows)
    Jmeter----生成HTML性能测试报告(Windows)
    nginx
    夜神模拟器 该网站的安全证书有问题 转载:https://bbs.yeshen.com/forum.php?mod=viewthread&tid=8864
    redis慢日志
    Nginx 转载:https://blog.csdn.net/yujing1314/article/details/107000737
    top 转载:https://mp.weixin.qq.com/s/kEY1U-CGIqQ2mKbr1aG8mA
    高可用
    shell 脚本 转载:https://mp.weixin.qq.com/s/rTsLIb2p-AE3oDPQXMQmLw
  • 原文地址:https://www.cnblogs.com/zhwl/p/2845281.html
Copyright © 2011-2022 走看看