CFMessagePort属于CoreFoundation框架中的类。因此可以在http://opensource.apple.com/tarballs/CF/CF-855.17.tar.gz中在源码,如果感兴趣可以去看看。
下面说下CFMessagePortRef的具体使用。
首先创建一个工程作为消息的接受者。
#import "ViewController.h"
#define LOCAL_MACH_PORT_NAME "com.message.demo"
@interface ViewController ()
{
CFMessagePortRef mMsgPortListenner;
}
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
UIButton *startPortButton = [[UIButton alloc] initWithFrame:CGRectMake(100, 200, 120, 40)];
[startPortButton setTitle:@"Start " forState:UIControlStateNormal];
startPortButton.backgroundColor = [UIColor grayColor];
[startPortButton addTarget:self action:@selector(start) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:startPortButton];
UIButton *endPortButton = [[UIButton alloc] initWithFrame:CGRectMake(100, 300, 120, 40)];
[endPortButton setTitle:@"End " forState:UIControlStateNormal];
endPortButton.backgroundColor = [UIColor grayColor];
[endPortButton addTarget:self action:@selector(end) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:endPortButton];
}
CFDataRef onRecvMsgCallBack(CFMessagePortRef local,SInt32 msgid,CFDataRef cfData,void *info)
{
NSLog(@"local = %@",local);
NSLog(@"msgid = %d",msgid);
NSString *strData = nil;
if (cfData)
{
const UInt8 * recvedMsg = CFDataGetBytePtr(cfData);
strData = [NSString stringWithCString:(char *)recvedMsg encoding:NSUTF8StringEncoding];
/**
实现数据解析操作
**/
NSLog(@"receive message:%@",strData);
}
//为了测试,生成返回数据
NSString *returnString = [NSString stringWithFormat:@"i have receive:%@",strData];
const char* cStr = [returnString UTF8String];
NSUInteger ulen = [returnString lengthOfBytesUsingEncoding:NSUTF8StringEncoding];
CFDataRef sgReturn = CFDataCreate(NULL, (UInt8 *)cStr, ulen);
return sgReturn;
}
- (void)start
{
if (0 != mMsgPortListenner && CFMessagePortIsValid(mMsgPortListenner)) {
CFMessagePortInvalidate(mMsgPortListenner);
}
mMsgPortListenner = CFMessagePortCreateLocal(kCFAllocatorDefault, CFSTR(LOCAL_MACH_PORT_NAME), onRecvMsgCallBack, NULL, NULL);
CFRunLoopSourceRef source = CFMessagePortCreateRunLoopSource(kCFAllocatorDefault, mMsgPortListenner, 0);
CFRunLoopAddSource(CFRunLoopGetCurrent(), source, kCFRunLoopCommonModes);
NSLog(@"start");
}
解释下面接收接收方法参数的意思
CFMessagePortRef 指接受消息对象的相关信息
例如:
local = <CFMessagePort 0x7f8391c0a110 [0x10800c7b0]>{locked = Maybe, valid = Yes, remote = No, name = com.message.demo, source = 0x7f8391d08240, callout = onRecvMsgCallBack (0x107362440), context = <CFMessagePort context 0x0>}
SInt32 msgid 给单条消息的标记
CFDataRef data 是消息发送的内容
void *info 可以携带其他数据对象进行传递,通常为空。
接下来再创建一个工程作为消息的发送者
#import "ViewController.h"
@interface ViewController ()
{
UITextField *textField;
}
@end
#define MSG_PORT "com.message.demo"
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
textField = [[UITextField alloc] initWithFrame:CGRectMake(50, 100, 100, 30)];
textField.backgroundColor = [UIColor grayColor];
[self.view addSubview:textField];
UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];
[btn setTitle:@"Send" forState:UIControlStateNormal];
[btn addTarget:self action:@selector(sendMethod) forControlEvents:UIControlEventTouchUpInside];
btn.frame = CGRectMake(50, 150, 100, 50);
[btn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
[self.view addSubview:btn];
}
- (void)sendMethod
{
[self sendMessageToDameonWith:textField.text msgID:101];
}
- (NSString *)sendMessageToDameonWith:(id)msgInfo msgID:(SInt32)msgid
{
CFMessagePortRef bRemote = CFMessagePortCreateRemote(kCFAllocatorDefault, CFSTR(MSG_PORT));
if (nil == bRemote) {
NSLog(@"bRemote create failed");
return nil;
}
NSString *msg = [NSString stringWithFormat:@"%@",msgInfo];
NSLog(@"send msg is :%@",msg);
const char *message = [msg UTF8String];
CFDataRef data,recvData = nil;
data = CFDataCreate(NULL, (UInt8 *)message, strlen(message));
/* 发送消息 */
CFMessagePortSendRequest(bRemote, msgid, data, 0, 100, kCFRunLoopDefaultMode, &recvData);
if (nil == recvData) {
NSLog(@"recvData data is nil.");
CFRelease(data);
CFMessagePortInvalidate(bRemote);
CFRelease(bRemote);
return nil;
}
const UInt8 *recvedMsg = CFDataGetBytePtr(recvData);
if (nil == recvedMsg) {
NSLog(@"receive data err.");
CFRelease(data);
CFMessagePortInvalidate(bRemote);
CFRelease(bRemote);
return nil;
}
NSString *strMsg = [NSString stringWithCString:(char *)recvedMsg encoding:NSUTF8StringEncoding];
NSLog(@"%@",strMsg);
CFRelease(data);
CFMessagePortInvalidate(bRemote);
CFRelease(bRemote);
CFRelease(recvData);
return nil;
}