线程和定时器

一:多线程

 

1,NSThread创建线程

 

  a,NSThread的类方法创建线程

   [NSThread detachNewThreadSelector:@selector(doing) toTarget:self withObject:nil];

 

 withObject 参数 下面几个方法类似

 

  b,构造方法创建线程需要start

 

   NSThread *th=[[NSThread alloc]initWithTarget:self selector:@selector(doing) object:nil];

    

 

        [th start];

 

 c,View创建

   [self performSelectorInBackground:@selector(doing) withObject:nil];

 

 

 

 

2,Operation创建线程

 

   a,Operation创建线程

   

//创建 Operation队列,add创建
NSOperationQueue *queue =[[NSOperationQueue alloc]init];
    
        [queue addOperationWithBlock:^{
    
           //执行方法
        }];

 

b,Operation启动多个线程,可设置线程的优先级

NSInvocationOperation *operation1=[[NSInvocationOperation alloc]initWithTarget:self selector:@selector(downloadImage:) object:@"1"];
    NSInvocationOperation *operation2=[[NSInvocationOperation alloc]initWithTarget:self selector:@selector(downloadImage:) object:@"2"];
    
    
    [operationQueue addOperation:operation1];
    [operationQueue addOperation:operation2];

 

 

 

3,GCD创建线程

   

  dispatch_queue_t queue=dispatch_queue_create("baihe", nil);
    
    dispatch_async(queue, ^{
      
    });

 

 

 

二:定时器

 

看下面的定时器操作

 [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(doing) userInfo:nil repeats:YES];该语句可能不会输出 ,可能会被return

 

解决办法://获得当前线程,防止被return,无法执行

    [[NSRunLoopcurrentRunLoop] run];

 

一般不在主线程中执行定时操作,开启线程使用自动释放池操作

 /**
     TimerInterval : 执行之前等待的时间。比如设置成1.0,就代表1秒后执行方法
     
     target : 需要执行方法的对象。
     
     selector : 需要执行的方法
     
     repeats : 是否需要循环
    */
    
    @autoreleasepool {

   NSTimer *timer=
    [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(doing) userInfo:nil repeats:YES];

        //RUNLoop管理定时器
//        [[NSRunLoop currentRunLoop]addTimer:timer forMode:NSDefaultRunLoopMode];
        

    //获得当前线程,防止被return,无法执行
    [[NSRunLoop currentRunLoop] run];
    
    
//    [timer invalidate];//停止定时器

 

 

 

 

以下是贪吃蛇的C语言代码,使用了线程定时器实现: ```c #include <stdio.h> #include <stdlib.h> #include <time.h> #include <conio.h> #include <windows.h> #define MAP_WIDTH 40 #define MAP_HEIGHT 20 #define SNAKE_INIT_LENGTH 3 #define SNAKE_MAX_LENGTH 100 // 定义方向 enum Direction { UP, DOWN, LEFT, RIGHT }; // 定义蛇的结构体 struct Snake { int x[SNAKE_MAX_LENGTH]; int y[SNAKE_MAX_LENGTH]; int length; enum Direction direction; }; // 定义食物的结构体 struct Food { int x; int y; }; // 定义地图 char map[MAP_HEIGHT][MAP_WIDTH]; // 定义蛇和食物 struct Snake snake; struct Food food; // 定义线程定时器 HANDLE hTimer; HANDLE hThread; // 初始化地图 void init_map() { int i, j; for (i = 0; i < MAP_HEIGHT; i++) { for (j = 0; j < MAP_WIDTH; j++) { if (i == 0 || i == MAP_HEIGHT - 1 || j == 0 || j == MAP_WIDTH - 1) map[i][j] = '#'; else map[i][j] = ' '; } } } // 初始化蛇 void init_snake() { int i; snake.length = SNAKE_INIT_LENGTH; snake.direction = RIGHT; for (i = 0; i < SNAKE_INIT_LENGTH; i++) { snake.x[i] = MAP_WIDTH / 2 - i; snake.y[i] = MAP_HEIGHT / 2; } } // 初始化食物 void init_food() { srand(time(NULL)); food.x = rand() % (MAP_WIDTH - 2) + 1; food.y = rand() % (MAP_HEIGHT - 2) + 1; } // 更新地图 void update_map() { int i, j; for (i = 0; i < MAP_HEIGHT; i++) { for (j = 0; j < MAP_WIDTH; j++) { if (i == 0 || i == MAP_HEIGHT - 1 || j == 0 || j == MAP_WIDTH - 1) map[i][j] = '#'; else map[i][j] = ' '; } } for (i = 0; i < snake.length; i++) { map[snake.y[i]][snake.x[i]] = '*'; } map[food.y][food.x] = '@'; } // 控制蛇的移动 void move_snake() { int i; for (i = snake.length - 1; i > 0; i--) { snake.x[i] = snake.x[i - 1]; snake.y[i] = snake.y[i - 1]; } switch (snake.direction) { case UP: snake.y[0]--; break; case DOWN: snake.y[0]++; break; case LEFT: snake.x[0]--; break; case RIGHT: snake.x[0]++; break; } } // 判断蛇是否吃到食物 void eat_food() { if (snake.x[0] == food.x && snake.y[0] == food.y) { snake.length++; if (snake.length > SNAKE_MAX_LENGTH) snake.length = SNAKE_MAX_LENGTH; init_food(); } } // 判断蛇是否撞墙或者撞到自己 int is_dead() { int i; if (snake.x[0] == 0 || snake.x[0] == MAP_WIDTH - 1 || snake.y[0] == 0 || snake.y[0] == MAP_HEIGHT - 1) return 1; for (i = 1; i < snake.length; i++) { if (snake.x[0] == snake.x[i] && snake.y[0] == snake.y[i]) return 1; } return 0; } // 游戏结束 void gameover() { printf("Game Over!\n"); printf("Press any key to continue...\n"); _getch(); exit(0); } // 控制蛇的方向 void control() { if (_kbhit()) { switch (_getch()) { case 'w': if (snake.direction != DOWN) snake.direction = UP; break; case 's': if (snake.direction != UP) snake.direction = DOWN; break; case 'a': if (snake.direction != RIGHT) snake.direction = LEFT; break; case 'd': if (snake.direction != LEFT) snake.direction = RIGHT; break; } } } // 定时器回调函数 VOID CALLBACK timer_callback(PVOID lpParameter, BOOLEAN TimerOrWaitFired) { move_snake(); eat_food(); update_map(); control(); if (is_dead()) gameover(); } // 线程函数 DWORD WINAPI thread_func(LPVOID lpParam) { while (1) { WaitForSingleObject(hTimer, INFINITE); } return 0; } // 主函数 int main() { init_map(); init_snake(); init_food(); update_map(); printf("Press any key to start...\n"); _getch(); hTimer = CreateWaitableTimer(NULL, FALSE, NULL); LARGE_INTEGER liDueTime; liDueTime.QuadPart = 0; SetWaitableTimer(hTimer, &liDueTime, 1000 / 10, timer_callback, NULL, FALSE); hThread = CreateThread(NULL, 0, thread_func, NULL, 0, NULL); while (1) { system("cls"); int i, j; for (i = 0; i < MAP_HEIGHT; i++) { for (j = 0; j < MAP_WIDTH; j++) { printf("%c", map[i][j]); } printf("\n"); } Sleep(1000 / 10); } return 0; } ``` 上面的代码中,使用了定时器线程来控制蛇的移动和游戏的进行。其中,定时器用来定时调用回调函数,线程用来等待定时器的信号。回调函数中包含了蛇的移动、吃食物、更新地图、控制方向等逻辑,线程函数中输出地图并等待定时器的信号。通过这种方式,可以实现一个简单的贪吃蛇游戏。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值