MAC COCOA一个简单的多线程程序[2]

 

MAC COCOA一个简单的多线程程序[2]

使用RUNLOOP计数,实现一个时间计数器和事件at the same time 运行。
STEP 1
H
CODE:
//
//  EDUAppDelegate.h
//  test_runloop_multithread
//
//  Created by DMD on 23/6/14.
//  Copyright (c) 2014 EDU. All rights reserved.
//

#import <Cocoa/Cocoa.h>

@interface EDUAppDelegate : NSObject <NSApplicationDelegate>

@property (assign) IBOutlet NSWindow *window;

@property (assign) IBOutlet NSTextField *m_Label_TotalCount;
@property (assign) IBOutlet NSTextField *m_Label_EveryStartCount;

@property (assign) IBOutlet NSTextField *m_Edit_SetCurrentNumber;

@property (assign) IBOutlet NSTextField *m_Label_EveryStartCount_Set;

@property (assign) IBOutlet NSTextField *m_Label_Restart;

@property  CFRunLoopSourceRef m_source1;
@property  CFRunLoopSourceContext m_source1_context;
@property  CFRunLoopTimerRef m_timer1;
@property  CFRunLoopTimerContext m_timer1_context;

@property NSString *m_total_str;
@property int m_total_count;

-(void)Show_Msg;

-(void) set_label_value:(int)value;

@end

M
CODE:
//
//  EDUAppDelegate.m
//  test_runloop_multithread
//
//  Created by DMD on 23/6/14.
//  Copyright (c) 2014 EDU. All rights reserved.
//

/****************************************
 Function : 1个线程来计数,另一个线程来接受用户输入的字符串,互相之间不干扰
 目的:测试多线程程序工作,了解原理
 *****************************************/

#import "EDUAppDelegate.h"

//Define Public Variable +++++
static int g_total_count=0;
static EDUAppDelegate *m_window_main;
//---------------------------

@implementation EDUAppDelegate

//define var +++
@synthesize m_Edit_SetCurrentNumber;
@synthesize m_Label_EveryStartCount;
@synthesize m_Label_EveryStartCount_Set;
@synthesize m_Label_TotalCount;
@synthesize m_Label_Restart;

@synthesize m_source1;
@synthesize m_source1_context;
@synthesize m_timer1;
@synthesize m_timer1_context;
@synthesize m_total_count;
@synthesize m_total_str;

//---------------
- (void)dealloc
{
    [super dealloc];
}

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
    // Insert code here to initialize your application
    m_window_main = self;
    m_total_count=0;
    m_total_str=@"";
}

-(void) set_label_value:(int)value
{
    NSString *myname;
    myname = [NSString stringWithFormat:@"Every Start Count:%d",value];
    
    m_total_str = [m_total_str stringByAppendingString:myname];
    m_total_str = [m_total_str stringByAppendingString:@"\n"];
    
    m_Label_EveryStartCount.stringValue = m_total_str;
    
    if((m_total_count>0 )&&(m_total_count % 5 ==0))
    {
        m_total_str=@"";
        m_Label_Restart.stringValue = @"Re-Start 0";
        m_total_count =0;
        [self Show_Msg];
    }

}
//+++++[一个多线程里面调用的函数,C++方式的函数,而不是Object-C方式]
// Call Function (2 Method)++
// Do thing 1
void my_do1(void *info __unused)
{
    m_window_main.m_total_count++;
    printf("Every Start Count: [%d] \n",m_window_main.m_total_count );    
    [m_window_main set_label_value:m_window_main.m_total_count];
    
    g_total_count++;
    printf("Total Count is :\"%d\" \n",g_total_count );
    m_window_main.m_Label_TotalCount.stringValue =[NSString stringWithFormat:@"Number is [%d]",g_total_count];
}
// Timer Function 1
void timer_function1(CFRunLoopTimerRef timer __unused, void *info)
{
    CFRunLoopSourceSignal(info);
}
// Call Function (2 Method)--
// START 
- (IBAction)OnBT_Start:(id)sender
{
    // 每一次Start时,一些变量需要Clear
    // 句柄:m_window_main 是本类的指针,必须初始化,一般为[ClassName1 alloc]init
    // 这里使用的是本身类,就直接 =self就可以了。
    m_window_main.m_total_count =0;
    
    m_Label_Restart.stringValue = @"Start!";
    m_total_str=@"";
    
    // 第一个线程:执行的事件 [begin] ++++++++
    //STEP 1 : [线程内容]初始化CFRunLoopSourceContext的空间
    bzero(&m_source1_context, sizeof(m_source1_context));
    //STEP 2 : [线程内容]调用要执行的函数
    m_source1_context.perform = my_do1;
    
    //STEP 3 : [线程源]初始化CFRunLoopSourceRef
    m_source1 = CFRunLoopSourceCreate(NULL, 0, &m_source1_context);
    //STEP 4 : 将线程源加到当前线程里面去
    CFRunLoopAddSource(CFRunLoopGetCurrent(), m_source1, kCFRunLoopCommonModes);
    //STEP 5 : 执行完,将线程源释放
    CFRelease(m_source1);
    
   // 第一个线程:执行的事件 [end] ++++++++
    
    // 第二个线程:一个时间计数器,用来启动上面的事件线程 [begin]+++++++++
    // STEP 1 初始化时间线程内容空间
    bzero(&m_timer1_context, sizeof(m_timer1_context));
    // STEP 2 [非常关键] 时间计数器的内容源头是上面的事件源头
    m_timer1_context.info = m_source1;
   
    // STEP 3 生成时间线程源头句柄
    m_timer1 = CFRunLoopTimerCreate(NULL, CFAbsoluteTimeGetCurrent(), 1, 0, 0,
                                     timer_function1, &m_timer1_context);
    
    // STEP 4 将时间源加入到时间计数列表里面
    CFRunLoopAddTimer(CFRunLoopGetCurrent(), m_timer1, kCFRunLoopCommonModes);
    CFRelease(m_timer1);
    //第二个线程:一个时间计数器,用来启动上面的事件线程 [end]--------
    
    //如果不用,就会在执行中,可以做其他的事件。但是在DOS环境状态,必须有这一行,在编译时才能看到。
    // CFRunLoopRun();
}

// STOP
- (IBAction)OnBT_Stop:(id)sender
{
    CFRunLoopRemoveSource(CFRunLoopGetCurrent(), m_source1, kCFRunLoopCommonModes);
    CFRunLoopRemoveTimer(CFRunLoopGetCurrent(), m_timer1, kCFRunLoopCommonModes);
    m_Label_Restart.stringValue = @"Stop!";
}

- (IBAction)OnBT_SetEveryStartCountNo:(id)sender
{
    m_Label_EveryStartCount_Set.stringValue = m_Edit_SetCurrentNumber.stringValue;
    g_total_count = [m_Label_EveryStartCount_Set.stringValue intValue];
}

- (IBAction)OnBT_CallSelfFunction:(id)sender
{
    [self OnBT_SetEveryStartCountNo:self];
}

// Show a MessageBox 
-(void)Show_Msg
{
    NSAlert *alert = [[[NSAlert alloc] init]autorelease];
    [alert setMessageText:@"Label captio is :"];
    [alert setInformativeText:@"Close"];
    [alert setAlertStyle:NSWarningAlertStyle];
    [alert runModal];
}

@end


运行效果图:


成功!
需要补充:在定义自身类的时候,一定要初始化 =self,这样才可以使用本身类里面的成员函数或者变量
完成!
特别补充,当你的工程里面加入了iostream等C++代码的时候,就需要将m后缀名修改为mm
这时候就需要将

 CFRunLoopSourceSignal((CFRunLoopSourceRef)info);

强制转换1下就可以了。
此语句在m文件里面也可以用。
修改方法,当说不匹配的时候,查找这个函数,发现类型和调用的void不同,就要强制转换。
完。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值