多线程

多线程的概念

当我们程序运行的时候,回默认开启主线程,开启事件循环。但是当我们需要执行一些耗时的操作时,需要在异步线程执行任务,不然app 的其他UI事件 因为在执行耗时操作会卡顿活着不响应事件。每个进程都会有一个线程,也可以有多个线程,打开我们的活动监视器可以看到。

因为耗时操作会影响主线程,下面我们就来模拟耗时操作

-(void)run:(id)obj{

    

    NSLog(@"%@",obj);

    

    //这是一个耗时操作--如果放在主线程,主线程的UI事件将无法处理

    CFAbsoluteTime startTime = CFAbsoluteTimeGetCurrent();

    int largeNum = 100*100;

    for (int i = 0; i < largeNum; ++i) {

        NSLog(@"%d",i);

    }

    CFAbsoluteTime endTime = CFAbsoluteTimeGetCurrent();

    NSLog(@"=======>%f",endTime - startTime);

}

我在StoryBoard里面拖入一个textView,我在 

-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event

这个方法里面调用上面的方法,发现当我触摸屏幕的时候,textView的事件无法响应,因为主线程卡了。

--->解决办法开启多线程来处理这个事件

方法一

1.NSThread 

官方API--

 /*

     An NSThread object controls a thread of execution. Use this class when you want to have an Objective-C method run in its own thread of execution. Threads are especially useful when you need to perform a lengthy task, but don’t want it to block the execution of the rest of the application. In particular, you can use threads to avoid blocking the main thread of the application, which handles user interface and event-related actions. Threads can also be used to divide a large job into several smaller jobs, which can lead to performance increases on multi-core computers.

     一个NSThread对象控制着一个线程的执行。实用这个类当你想要有一个OC方法运行在它自己的线程。多线程在你执行一个耗时操作的时候特别有用,但不要阻塞其他应用的执行。特别地,你可以使用多线程避免阻塞主线程的应用,主线程处理用户交互和相关的响应事件。多线程也可以被用于分离一个大的任务成几个小的任务,它可以充分的利用一个设备的多喝

     */


具体使用步骤

// 1.0创建一条新的线程

/**

     Description:Returns an NSThread object initialized with the given arguments  返回一个用参数初始化的NSThread对象

     - parameter run: The selector for the message to send to target. This selector must take only one argument and must not have a return value.  run: 这个方法是发送消息給target对象。这个方法必须只有一个参数没有返回值

     */

NSThread *thread =[[NSThread alloc]initWithTarget:self selector:@selector(run:) object:@"hello"];

// 这种方法创建的线程需要手动开启

[thread start];

// 2.0分离出一条新的线程

/**

     *  Description:Detaches a new thread and uses the specified selector as the thread entry point.分离出一条新的线程,实用指定的方法作为这条线程的入口

     *  @param run: 这条线程上执行的方法

     *  @return 返回值

     */

[NSThread detachNewThreadSelector:@selector(run:) toTarget:self withObject:@"danny"];

// 3.0隐式开启一条线程

    [self performSelectorInBackground:@selector(run:) withObject:@"wahaha"];

//4.0 实用GCD

    dispatch_async(dispatch_get_global_queue(0, 0), ^{

        [self run:@"heheh"];

    });

//5.1 使用 NSOperationQueue 配合 NSInvocation 方法实现

 NSOperationQueue *queue =[[NSOperationQueue alloc]init];

    SEL run = @selector(run:);

    NSMethodSignature *methodSignature =[ViewController instanceMethodSignatureForSelector:run];

    /*

     // 注意 设置参数

     Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '+[NSInvocation _invocationWithMethodSignature:frame:]: method signature argument cannot be nil'

     */

    /*

     官方的API是这么讲的  必须设置方法 设置参数  在唤醒这个操作

     The new object must have its selector set with setSelector: and its arguments set with setArgument:atIndex: before it can be invoked. Do not use the alloc/init approach to create NSInvocation objects.

     */

    NSInvocation *invocation =[NSInvocation invocationWithMethodSignature:methodSignature];

    [invocation setTarget:self];

    NSString *str =@"hehheh";

    [invocation setArgument:&str atIndex:2];

    [invocation setSelector:@selector(run:)];

    NSInvocationOperation *invocationOp =[[NSInvocationOperation alloc]initWithInvocation:invocation];

    [queue addOperation:invocationOp];

//5.2 使 用 NSOperationQueue 配合 NSInvocation 方法实现 换一种创建invocation的方法

 NSOperationQueue *queue =[[NSOperationQueue alloc]init];

     NSInvocationOperation *invocationOp =[[NSInvocationOperation alloc]initWithTarget:self selector:@selector(run:) object:@"james"];

     [invocationOp setCompletionBlock:^{

     NSLog(@"%@",[NSThread currentThread]);//>NSThread: 0x7fcfb3d2e700>{number = 2

     

     }];

    [queue addOperation:invocationOp];

//5.3 使用 NSOperationQueue 配合 NSBlockOperation 方法实现 

NSOperationQueue *queue =[[NSOperationQueue alloc]init];

    NSBlockOperation *blockOp =[NSBlockOperation blockOperationWithBlock:^{

        NSLog(@"blockOp%@",[NSThread currentThread]);

        [self run:@"hehhe"];

    }];

    [queue addOperation:blockOp];

//  关于NSOperationQueue

   NSOperationQueue的作用,NSOperation可以调用start方法来执行任务,但是默认是同步执行的

   如果将NSOperation添加到NSOperationQueue中,系统会自动异步执行NSOperationQueue里面的操作。

----那么我们来看看官方文档是怎么解释的

/*

     The NSOperationQueue class regulates the execution of a set of NSOperation objects. After being added to a queue, an operation remains in that queue until it is explicitly canceled or finishes executing its task. Operations within the queue (but not yet executing) are themselves organized according to priority levels and inter-operation object dependencies and are executed accordingly. An application may create multiple operation queues and submit operations to any of them.

     NSOperationQueue这个类常规的执行一组NSOperation对象。当操作被添加到队列,一个操作一致存在于那个队列直到显式地取消和完成它的任务。在操作队列里面的操作(还没有执行的)他们根据优先级和内部的操作依赖关系,自行排好队列,并根据这个队列依次执行。一个应用程序可以创建多个操作队列并且可以提交他们里面的任意操作

     */




//补充 pthread实现多线程

-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{

    // pthread是一套通用的多线程API。适用于linux/unix/windows等系统,跨平台可移植,使用难度大

    //创建线程

    pthread_t thread;//定义一个pthread_t类型的结构体变量

    void * (*funp)(void *) = fun; //定义void *(*)(void *)类型的函数指针

    pthread_create(&thread, NULL, funp, NULL);//用过调用pthread_create,传入传入thread指针参数创建线程,传入函数指针指定要执行的代码块

}



/*

  pthread_create 回调函数,通过此函数作为子线程的执行的代码块

 */

void *fun(void *param){

    NSLog(@"%@",[NSThread currentThread]);

     CFAbsoluteTime startTime = CFAbsoluteTimeGetCurrent();

    int largeNum = 100*100;

    for (int i = 0; i < largeNum; ++i) {

        NSLog(@"%d",i);

    }

    CFAbsoluteTime endTime = CFAbsoluteTimeGetCurrent();

    NSLog(@"=======>%f",endTime - startTime);

    return NULL;

}













  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值