2011-10-13 20 views
11

Gần đây tôi đã chuyển từ sử dụng kqueue sang GCD dispatch sources để theo dõi thay đổi tệp. Điều này đã làm việc tốt và dẫn đến một API đơn giản hơn nhiều. Tôi ghi lại chuyển đổi của tôi here. Vấn đề duy nhất tôi có là bây giờ tôi không thể truy cập vào các lá cờ trên sự kiện mà tôi đã có thể trong kqueue. Ví dụ với kqueue tôi đã có thể kiểm tra xem các tập tin đã bị xóa, đổi tên, hoặc các thuộc tính của nó đã được thay đổi như sau:Grand Central Dispatch (GCD) gửi cờ nguồn

struct kevent event; 

... 

if(event.flag & EV_DELETE) 
{ 
    printf("File was deleted\n"); 
} 

là API này không có sẵn với GCD hay tôi cần phải thiết lập các nguồn công văn lên cho mỗi lá cờ tôi muốn nghe. Hoặc là tốt nhất để sử dụng kqueue vì nó cung cấp khả năng hiển thị lớn hơn cho sự kiện đã xảy ra.

+3

Tôi đã không thực sự đọc câu hỏi của bạn, nhưng tôi đã chỉnh sửa nó để danh tiếng của bạn có thể là 1337. Ok tôi sẽ đọc ngay bây giờ. – morningstar

Trả lời

8

Tôi đã tìm thấy câu trả lời trong số Concurrency Programming Guide. Tôi đã lần đầu tiên nhìn vào GCD Reference nhưng không có may mắn. Đường liên quan từ hướng dẫn là

Đối với nguồn gửi mô tả giám sát hoạt động của hệ thống tệp, hàm này trả về hằng số cho biết loại sự kiện đã xảy ra. Để biết danh sách các hằng số, hãy xem dispatch_source_vnode_flags_t loại liệt kê.

Dưới đây là ví dụ về cách bạn có thể sử dụng.

dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); 
int fildes = open("path/to/some/file", O_EVTONLY); 
__block dispatch_source_t source = dispatch_source_create(DISPATCH_SOURCE_TYPE_VNODE,fildes, 
                DISPATCH_VNODE_DELETE | DISPATCH_VNODE_WRITE | DISPATCH_VNODE_EXTEND | DISPATCH_VNODE_ATTRIB | DISPATCH_VNODE_LINK | DISPATCH_VNODE_RENAME | DISPATCH_VNODE_REVOKE, 
                queue); 
dispatch_source_set_event_handler(source,^
{ 
    unsigned long flags = dispatch_source_get_mask(source); 
    if(flags & DISPATCH_VNODE_DELETE) 
     printf("DISPATCH_VNODE_DELETE\n"); 
    if(flags & DISPATCH_VNODE_WRITE) 
     printf("DISPATCH_VNODE_WRITE\n"); 
    if(flags & DISPATCH_VNODE_EXTEND) 
     printf("DISPATCH_VNODE_EXTEND\n"); 
    if(flags & DISPATCH_VNODE_ATTRIB) 
     printf("DISPATCH_VNODE_ATTRIB\n"); 
    if(flags & DISPATCH_VNODE_LINK) 
     printf("DISPATCH_VNODE_LINK\n"); 
    if(flags & DISPATCH_VNODE_RENAME) 
     printf("DISPATCH_VNODE_RENAME\n"); 
    if(flags & DISPATCH_VNODE_REVOKE) 
     printf("DISPATCH_VNODE_REVOKE\n"); 
}); 
dispatch_source_set_cancel_handler(source, ^(void) 
{ 
    close(fildes); 
}); 
dispatch_resume(source); 
+0

Cảm ơn bạn, điều đó thật tuyệt vời. Tôi đã sử dụng một bài đăng trên [bài đăng trên blog] của bạn (http://www.davidhamrick.com/2011/10/13/Monitoring-Files-With-GCD-Being-Edited-With-A-Text-Editor.html). Tuy nhiên, bạn nên sửa dòng 17 từ '[blockSelf watchStyleSheet: path];' thành '[blockSelf watchConfigFile: path];'. –

+0

không có điểm cho 'nguồn' là' __block' vì nó không bao giờ được gán cho – user102008

3

Bạn có thể thay đổi * dispatch_source_get_mask (nguồn) * để * dispatch_source_get_data (nguồn) *, như dispatch_source_get_mask (nguồn) trả về tất cả những lá cờ bạn thông qua trong việc tạo ra các bộ xử lý thay vì các sự kiện được tạo.

Các vấn đề liên quan