2014-04-08 2 views
5

लागू बिना चलाता है क्यों निम्नलिखित कोड काम करता है? यह एक छोटा कोको प्रोग्राम है जो फ़ाइल चुनने के लिए NSOpenPanel का उपयोग करता है और इसे Emacs.app में खोलता है। इसे प्रारंभिक निर्देशिका के साथ कमांड लाइन से तर्क के रूप में चलाया जा सकता है।कैसे यह है कि कोको जीयूआई कक्षा NSApplication या NSRunLoop

कैसे NSOpenPanel NSApplication या NSRunLoop लागू बिना चलता है? कोको कार्यक्रम पर सीमाएं क्या हैं जो स्पष्ट रूप से एनएसएप्लिकेशन या एनएसआरन लूप शुरू नहीं करती हैं? मैंने सोचा होगा कि उनमें से एक था: आप किसी भी प्रकार की जीयूआई का उपयोग नहीं कर सकते। शायद NSOpenPanel का आह्वान करके, कुछ फ़ॉलबैक कोड को बुलाया जा रहा है जो NSRunLoop को आमंत्रित करता है? मैंने + [एनएसपीप्लिकेशन एलोक] और + [एनएसआरन लूप एलोक] पर ब्रेकपॉइंट लगाए और वे ट्रिगर नहीं हुए।

main.m: 

#import <Cocoa/Cocoa.h> 

NSString *selectFileWithStartPath(NSString *path) { 
    NSString *answer = nil; 
    NSOpenPanel* panel = [NSOpenPanel openPanel]; 
    panel.allowsMultipleSelection = NO; 
    panel.canChooseFiles = YES; 
    panel.canChooseDirectories = NO; 
    panel.resolvesAliases = YES; 
    if([panel runModalForDirectory:path file:nil] == NSOKButton) 
    answer = [[[panel URLs] objectAtIndex:0] path]; 
    return answer; 
} 

int main(int argc, const char * argv[]) { 
    NSString *startPath = argc > 1 ? [NSString stringWithUTF8String:argv[1]] : @"/Users/Me/Docs"; 
    printf("%s\n", argv[1]); 
    BOOL isDir; 
    if([[NSFileManager defaultManager] fileExistsAtPath:startPath isDirectory:&isDir] && isDir) { 
    system([[NSString stringWithFormat:@"find %@ -name \\*~ -exec rm {} \\;", startPath] UTF8String]); 
    NSString *file = selectFileWithStartPath(startPath); 
    if(file) [[NSWorkspace sharedWorkspace] openFile:file withApplication:@"Emacs.app"]; 
    } 
} 

उत्तर

5

runModalForDirectory:file:types: अपना स्वयं का ईवेंट लूप बनाता है और चलाता है। प्रलेखन से:

प्रदर्शित करता है पैनल और एक मॉडल घटना पाश कि समाप्त होता है जब उपयोगकर्ता ठीक या रद्द करें क्लिक करता है शुरू होता है।

आप देख सकते हैं कि यह भी आप इस कार्यक्रम को रोक देते हैं, जबकि "खोलें" संवाद सक्रिय है और डीबगर कंसोल में आईएसपी नामों को मुद्रित:

frame #0: 0x00007fff8b855a1a libsystem_kernel.dylib`mach_msg_trap + 10 
frame #1: 0x00007fff8b854d18 libsystem_kernel.dylib`mach_msg + 64 
frame #2: 0x00007fff8549f155 CoreFoundation`__CFRunLoopServiceMachPort + 181 
frame #3: 0x00007fff8549e779 CoreFoundation`__CFRunLoopRun + 1161 
frame #4: 0x00007fff8549e0b5 CoreFoundation`CFRunLoopRunSpecific + 309 
frame #5: 0x00007fff88381a0d HIToolbox`RunCurrentEventLoopInMode + 226 
frame #6: 0x00007fff883817b7 HIToolbox`ReceiveNextEventCommon + 479 
frame #7: 0x00007fff883815bc HIToolbox`_BlockUntilNextEventMatchingListInModeWithFilter + 65 
frame #8: 0x00007fff838ca3de AppKit`_DPSNextEvent + 1434 
frame #9: 0x00007fff838c9a2b AppKit`-[NSApplication nextEventMatchingMask:untilDate:inMode:dequeue:] + 122 
frame #10: 0x00007fff83c28e2e AppKit`-[NSApplication _realDoModalLoop:peek:] + 642 
frame #11: 0x00007fff83c2754e AppKit`-[NSApplication runModalForWindow:] + 117 
frame #12: 0x00007fff83ef5d0b AppKit`-[NSSavePanel runModal] + 276 
frame #13: 0x0000000100000c61 xxx`selectFileWithStartPath(path=0x00000001000010b8) + 225 at main.m:18 
frame #14: 0x0000000100000e0d xxx`main(argc=1, argv=0x00007fff5fbff9c0) + 189 at main.m:26 

आप फ्रेम # 11 में देख सकते हैं , -[NSApplication runModalForWindow:] "खोलें" संवाद के लिए एक मॉडल घटना पाश को चलाने के लिए प्रयोग किया जाता है।

+0

हाँ, मैं देख रहा हूँ। शीघ्र प्रतिक्रिया के लिए शुक्रिया। एक बात मैं सिर्फ महसूस किया है कि पुराने क्लासिक एप्पल main.m कॉल [NSApplication sharedApplication], नहीं [NSApplication alloc]। मेरा अनुमान है कि कि runModalForWindow करने के लिए कॉल एप्पल पुस्तकालय में एक सिंगलटन [NSApplication sharedApplication] instantiating से पहले हो सकता है। – Colin

संबंधित मुद्दे