创建DISPATCH_SOURCE_TYPE_WRITE派发源

47 篇文章 0 订阅
34 篇文章 0 订阅
向文件或socket写入数据非常类似于读取数据,配置描述符为写入操作后,创建一个 DISPATCH_SOURCE_TYPE_WRITE 类型的dispatch source,创建好之后,系统会调用事件处理器,让它开始向文件或socket写入数据。当你完成写入后,使用 dispatch_source_cancel 函数取消dispatch source。
写入数据也应该配置文件描述符使用非阻塞操作,虽然 dispatch_source_get_data 函数可以查看当前有多少可用写入空间,但这个值只是建议性的,而且在你执行写入操作时可能会发生变化。如果发生错误,写入数据到阻塞描述符,也会使事件处理器停止在执行中途,并阻止dispatch queue执行其它任务。串行queue会产生死锁,并发queue则会减少能够执行的任务数量。
下面是使用dispatch source写入数据到文件的例子,打开文件后,函数传递文件描述符到事件处理器。getData函数负责提供要写入的数据,在数据写入到文件之后,事件处理器取消dispatch source,阻止再次调用。此时dispatch source的拥有者需负责释放dispatch source。

#import <Foundation/Foundation.h>
static char *string = "这是一个测试::2017";


size_t getDataSize(){

    return strlen(string);
}

size_t getData(void *buffer, size_t bufferSize){

    size_t length = strlen(string);
    size_t loopCount = length;
    if (bufferSize < length) {
        loopCount = bufferSize;
    }
    
    for (int i = 0; i < loopCount; i++) {
        ((char*)buffer)[i] = string[i];
    }
    
    return loopCount;
}

dispatch_source_t createWriteOperationFileDescriptionDispatchSource(const char* filename)
{
    //注意:open的第三个参数,仅在有O_CREAT标记时生效
    int fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC,
                  (S_IRUSR | S_IWUSR | S_ISUID | S_ISGID));
    if (fd == -1)
        return NULL;
    fcntl(fd, F_SETFL, O_NONBLOCK); // avoid blocking during the write.
    
    //最好使用串行队列一个一个的写入
    dispatch_queue_t queue = dispatch_queue_create("串行队列标记", NULL);
    dispatch_source_t writeSource = dispatch_source_create(DISPATCH_SOURCE_TYPE_WRITE,
                                                           fd, 0, queue);
    if (!writeSource)
    {
        close(fd);
        return NULL;
    }
    
    dispatch_source_set_event_handler(writeSource, ^{
        size_t bufferSize = getDataSize();
        void* buffer = malloc(bufferSize);
        
        size_t actual = getData(buffer, bufferSize);
        write(fd, buffer, actual);
        
        free(buffer);
        
        // Cancel and release the dispatch source when done.
        dispatch_source_cancel(writeSource);
    });
    
    dispatch_source_set_cancel_handler(writeSource, ^{
        close(fd);
    });
    dispatch_resume(writeSource);
    return (writeSource);
}

int main(int argc, const char * argv[]) {

    @autoreleasepool {
        NSLog(@"==========描述符派发源===========");
        createWriteOperationFileDescriptionDispatchSource("/Users/feinno/Desktop/test");
        
        [[NSRunLoop currentRunLoop]runUntilDate:[NSDate dateWithTimeIntervalSinceNow:3]];
    }

    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值