`

Pre Load

    博客分类:
  • ios
阅读更多

在app store中的很多应用程序非常的笨重,他们有好的界面,但操作性很差,比如说当程序从网上或本地载入数据的时候,界面被冻结了,用户只能等程序完全载入数据之后才能进行操作。
当打开一个应用程序时,iphone会产生一个包含main方法的线程,所用程序中的界面都是运行在这个线程之中的(table views, tab bars, alerts…),有时候我们会用数据填充这些view,现在问        题是如何有效的载入数据,并且用户还能自如的操作程序。方法是启动新的线程,专门用于数据的下载,而主线程不会因为下载数据被阻塞。
不管使用任何编程语言,在实现多线程时都是一件很麻烦的事情。更糟糕的是,一旦出错,这种错误通常相当糟糕。然而,幸运的是apple从os x10.5在这方面做了很多的改进,NSThread的引入,使得开发多线程应用程序容易多了。除此之外,它们还引入了两个全新的类,NSOperation和NSOperationQueue。
接下来我们通过一个实例来剖析如何使用这两个类实现多线程。这里指示展示这两个类的基本用法,当然这不是使用他们的唯一办法。
如果你熟悉java或者它的别的变种语言的话 ,你会发现NSOperation对象很像java.lang.Runnable接口,就像java.lang.Runnable接口那样,NSOperation类也被设计为可扩展的,而且只有一个需要重写的方法。它就是-(void)main。使用NSOperation的最简单的方式就是把一个NSOperation对象加入到NSOperationQueue队列中,一旦这个对象被加入到队列,队列就开始处理这个对象,直到这个对象的所有操作完成。然后它被队列释放。
下面的例子中,使用一个获取网页,并对其解析程NSXMLDocument,最后将解析得到的NSXMLDocument返回给主线程。
    
PageLoadOperation.h@interface PageLoadOperation : NSOperation {
    NSURL *targetURL;}
@property(retain) NSURL *targetURL;
- (id)initWithURL:(NSURL*)url;@end

PageLoadOperation.m
#import "PageLoadOperation.h"#import "AppDelegate.h"@implementation PageLoadOperation@synthesize targetURL;- (id)initWithURL:(NSURL*)url;{
    if (![super init]) return nil;
    [self setTargetURL:url];
    return self;}- (void)dealloc {
    [targetURL release], targetURL = nil;
    [super dealloc];
}
- (void)main 
{
    NSString *webpageString = [[[NSString alloc]
    initWithContentsOfURL:[self targetURL]] autorelease];
    NSError *error = nil;
    NSXMLDocument *document = [[NSXMLDocument alloc]
    initWithXMLString:webpageString 
    options:NSXMLDocumentTidyHTML error:&error];
    if (!document) {
        NSLog(@"%s Error loading document (%@): %@", 
        _cmd, [[self targetURL] absoluteString], error);
         return;
    }
    [[AppDelegate shared]
    performSelectorOnMainThread:@selector(pageLoaded:)
         withObject:document waitUntilDone:YES];
    [document release];
}
@end
    正如我们所看到的那样,这个类相当的简单,在它的init方法中接受一个url并保存起来,当main函数被调用的时候,它使用这个保存的url创建一个字符串,并将这个字符串传递给NSXMLDocumentinit方法。如果加载的xml数据没有出错,数据会被传递给AppDelegate,它处于主线程中。到此,这个线程的任务就完成了。在主线程中注销操作队列的时候,会将这个NSOperation对象释放。
AppDelegate.h
@interface AppDelegate : NSObject {
    NSOperationQueue *queue;
}+ (id)shared;- (void)pageLoaded:(NSXMLDocument*)document;@endAppDelegate.m        #import "AppDelegate.h"#import "PageLoadOperation.h"@implementation AppDelegate
static AppDelegate *shared;
static NSArray *urlArray;
- (id)init
{
    if (shared)
    {
        [self autorelease];
        return shared;
    }
    if (![super init]) return nil;    NSMutableArray *array = [[NSMutableArray alloc] init];[array addObject:@"http://www.google.com"];[array addObject:@"http://www.apple.com"];[array addObject:@"http://www.yahoo.com"];[array addObject:@"http://www.zarrastudios.com"];[array addObject:@"http://www.macosxhints.com"];urlArray = array;    queue = [[NSOperationQueue alloc] init];shared = self;return self;
    }
    •    (void)applicationDidFinishLaunching:
    (NSNotification *)aNotification
{
        for (NSString *urlString in urlArray) 
        {
        NSURL *url = 
        [NSURL URLWithString:urlString];        PageLoadOperation *plo = 
        [[PageLoadOperation alloc] initWithURL:url];
        [queue addOperation:plo];
        [plo release];
        }
}
- (void)dealloc
{
        [queue release], queue = nil;
        [super dealloc];
}
+ (id)shared;
{
        if (!shared) {
            [[AppDelegate alloc] init];
        }
        return shared;
}
- (void)pageLoaded:(NSXMLDocument*)document;
{
        NSLog(@"%s Do something with the XMLDocument: %@",
             _cmd, document);
}
@end

NSOperationQueue的并行控制(NSOperationQueue Concurrency)
        在上面这个简单的例子中,我们很难看出这些操作是并行运行的,然而,如果你你的操作花费的时间远远比这里的要长,你将会发现,队列是同时执行这些操作的。幸运的是,如果你想要为队列限制同时只能运行几个操作,你可以使用NSOperationQueue的setMaxConcurrentOperationCount:方法。例如,[queue setMaxConcurrentOperationCount:2];

分享到:
评论

相关推荐

    LS-DYNA_Bolt_Pre-Load_2019.pdf

    LS-DYNA Bolt Pre-Load 方法详解 LS-DYNA 是一种广泛应用于结构仿真和碰撞分析的Finite Element Analysis(有限元分析)软件。其中,螺栓预紧是结构设计和分析中非常重要的一步。LS-DYNA 提供了多种螺栓预紧的方法...

    最简单的线刷方式sideload

    "最简单的线刷方式sideload"是指通过ADB(Android Debug Bridge)进行系统更新的一种简便流程。在Android开发和调试中,ADB是一个不可或缺的工具,它允许开发者在计算机上远程控制和管理Android设备。 1. **ADB...

    带load、clr等功能的寄存器.vhd.txt

    d, clk, clr, pre, load, data : IN BIT; q1, q2, q3, q4, q5, q6, q7 : OUT BIT ); END reginf; ``` 实体`reginf`定义了寄存器的输入和输出端口。输入端口包括: - `d`:数据输入。 - `clk`:时钟信号。 - `clr`...

    xulrunner-1.9.2.28pre.en-US.linux-x86_64.tar.rar

    org.eclipse.swt.SWTError: No more handles [MOZILLA_FIVE_HOME=''] (java.lang.UnsatisfiedLinkError: Could not load SWT library. Reasons: no swt-mozilla-gtk-4335 in java.library.path no swt-mozilla-gtk ...

    pre-commit-ci-config:验证pre-commit.ci配置

    >>> from pre_commit.clientlib import load_config >>> from pre_commit_ci_config import SCHEMA >>> cfg = load_config( ' .pre-commit-config.yaml ' ) >>> cfg = cfgv.validate(cfg, SCHEMA ) >>> cfg = cfgv....

    sqlload 文档

    与 DB2 的 Load 工具相比,SQL*Loader 提供了更多的功能选项,包括灵活的加载模式、可选的加载策略以及支持多表加载等特性。 #### 二、SQL*Loader 的基本使用方法 使用 SQL*Loader 需要通过命令行调用 `sqlldr` ...

    LS-PrePost Hex-Meshing

    1. **Load model**:首先,你需要导入你的几何模型。LS-PrePost支持多种格式的模型文件,如IGES、STEP或STL等,你可以选择适合你的文件类型加载模型。 2. **Check model**:加载模型后,进行模型检查是非常重要的。...

    CImg 2.0.5_pre092517

    例如,`load`和`save`函数用于加载和保存图像文件,支持多种常见格式如BMP、JPEG、PNG等;`display`函数可以快速地在窗口中显示图像;`resize`函数实现图像的尺寸调整;`rotate`函数可以进行图像的旋转;`blur`和`...

    LS-PrePost的hex meshing功能

    用户应通过"Load model"加载模型,然后通过"Check model"功能仔细检查模型是否有任何缺陷。如果发现模型不是实体(solid),即存在内部空洞或未闭合的边界,那么必须先进行修复。 接下来是“准备修剪工具”...

    xulrunner-1.9.2.28pre.en-US.linux-x86_64.tar

    解决org.eclipse.swt.SWTError: No more handles [MOZILLA_FIVE_HOME=''] (java.lang.UnsatisfiedLinkError: Could not load SWT library. Reasons: no swt-mozilla-gtk-4335 in java.library.path

    Eurocode_1_Part1.4_(Wind_load)(2004_Jan).pdf

    根据提供的文件信息,该文件的标题为“Eurocode_1_Part1.4_(Wind_load)(2004_Jan).pdf”,描述为“Eurocode_1_Part1.4_(Wind_load)(2004_Jan)”,标签为“wind load”,以及部分内容。我们可以从中提取出以下知识点...

    使用PYTHON解析Wireshark的PCAP文件方法

    PYTHON首先要安装scapy模块 PY3的安装scapy-python3,使用PIP...<pre name=code class=python>packet=pcaps[0] #第1个数据包结构 packet.time#数据包时间戳 packet[Raw].load#PY3读取节点数据方法,packet[IP].src;pac

    jQuery.lazyload+masonry改良图片瀑布流代码

    /** * 自动刷新 * @type {*|jQuery|HTMLElement} */ var $container = $('#main'); $container.imagesLoaded( function(){ $container.masonry({ itemSelector : '.item', columnWidth:205, ...var pre_href;

    coding-check.zip

    在编程和软件开发领域,代码检查是一个至关重要的过程,它涉及到对源代码的质量评估和问题检测,以确保软件的稳定性和可维护性。"coding-check.zip" 文件很可能包含了一组用于进行代码检查的工具、脚本或者示例,...

    android dx.jar

    解决 Error:Android Pre Dex: [dx.jar] Failed to load dx.jar 问题

    Pre'o;iohlhoilo

    此外,文档还提到了几个关键操作步骤,如启动会话(Start session)、加载记录(Load record)、停止会话(Stop session)等,这些步骤构成了整个系统的运行流程。 #### 技术挑战与限制 文档中提到的一些技术挑战和...

    pytorch加载自定义网络权重的实现

    这个错误是因为尝试从一个字典对象加载权重,而`torch.load()`函数需要一个可寻址的文件对象,如`io.BytesIO`。 首先,让我们深入理解这个问题的原因。当你使用`torch.save(net.state_dict(), 'net.pkl')`来保存...

    【SpringBoot】Error: Could not find or load main class org.apache.hadoop.mapreduce.v2.app.MRAppMaster

    【SpringBoot】Error: Could not find or load main class org.apache.hadoop.mapreduce.v2.app.MRAppMaster报错明细问题解决后记 报错明细 IDEA SpringBoot集成hadoop运行环境,,本地启动项目,GET请求接口触发...

    VxWorks-system-load.rar_vxworks_vxworks image

    "VxWorks-system-load.rar_vxworks_vxworks image"这个压缩包文件聚焦于VxWorks的系统映像及其加载过程,这对于理解和调试VxWorks系统至关重要。 VxWorks的映像是一个静态编译的结果,包含了操作系统内核、库函数、...

    Sphinx入门.docx

    1. 在使用 Sphinx 时可能会出现一些错误,例如 sql_connect: failed to load libmysqlclient。 2. 解决方法是修改 /etc/ld.so.conf 文件,添加 /usr/lib64/mysql 路径,然后运行 ldconfig 命令。 Sphinx 是一个功能...

Global site tag (gtag.js) - Google Analytics