2012-01-24 7 views
1

同じことをするためにPythonを使用することに関して同様の質問を投稿しましたが、私はobjective-cとCocoaを使用してこの小さなプログラムを書き直しました。ここにもう一つのStack Overflowの質問があります:https://stackoverflow.com/questions/8980677/polling-nsfontmanager-sharedfontmanager-in-python質問をもう一度投稿する目的は、Objective-CとCocoaの専門家に手を差し伸べることです。だからここに行く。ココアのフォントをアクティブにしている間にNSFontManagerから利用可能なフォントを更新する

私は、OS Xがアクティブであると見なすフォントのリストを取得し、一定期間にわたってアクティブな数を報告する小さな端末プログラムを作成しようとしています。たとえば、プログラムの実行中に120フォントをアクティブにすると、120フォントがアクティブになっているはずです。プログラム実行中にさらに10フォントをアクティブにすると、130フォントがアクティブであると報告されます。私が実行している問題は、sharedFontManagerインスタンスがforループで更新しているようには見えないということです。ここで私が働いているコードです:

#import <Foundation/Foundation.h> 
#import <AppKit/AppKit.h> 

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

    @autoreleasepool { 
     for(int y=0; y < 5; y++){ 

     NSArray *sysFonts; 
     NSFontManager *manager = [NSFontManager sharedFontManager]; 
     sysFonts = [manager availableFonts]; 

     NSLog(@"Number of active fonts: %lu", [sysFonts count]); 
     sleep(5); 
     sysFonts = nil; 
     } 

    } 
return 0; 
} 

をですから、これをテストしたい場合は、アクティブと非アクティブにする数百のフォントが必要になります。フォントを無効にして起動します(フォントを選択し、右クリックし、「フォントを無効にする」を選択します)。プログラムを実行します。 「アクティブフォント数:」という端末がフォントブックにポップアップしたら、選択したフォントを右クリックして「フォントを有効にする」をクリックします(sleep(5)を長めに変更してください)。秒で)、ループを5回繰り返します(この数字も変更できます)。

結局のところ、私は結局のところ、同じ数の起動フォントを使用していますが、これは不正確であることがわかりました。なぜなら、多数のフォント(約500フォント)を起動しても、多数のフォントを有効にしたのか無効にしたのかに応じて、プログラムを実行した前回の回数よりも数が増減していることがわかります。言い換えれば、私はフォントの活性化が発生していることを知っている、と私はフォントの数が変化するのを見て期待しています。

ご迷惑をおかけして申し訳ございません。

+0

これは本当に良い質問です。私は間違いなくここで問題を再現することができ、フォントマネージャがなぜ更新されないのかわかりません。 '[manager availableFonts]'を呼び出す直前にプライベートメソッド '-_reactToFontSetChange'を呼び出すことで更新することができましたが、それは理想的ではありません。 –

+0

時間をかけてくれてありがとう@RobKeniger!私がしようとしていることをする方法を見つけた場合は、私に知らせてください。あなたは、プライベートメソッド '_reactToFontSetChange'を呼び出すことによって更新を得ることができたと言いました。それは理想的ではないと信じていますが、それが唯一の方法なら、プライベートメソッドをどのように呼び出すのか教えてください。私はプログラミングに少し新鮮ですが、私はかなり素早くつかまえます。 :) – Semibeard

+0

最も簡単な方法は '[manager performSelector:@selector(_reactToFontSetChange)]'を呼び出すことです。 –

答えて

3

NSRunLoopを実行し、NSFontSetChangedNotificationメカニズムを使用してsharedFontManagerインスタンスを更新することができます。

/* 

Getting updated availableFonts from NSFontManager while activating fonts in Cocoa 
http://stackoverflow.com/questions/8995017/getting-updated-availablefonts-from-nsfontmanager-while-activating-fonts-in-coco 

references: 
- NSFontAttributeExplorer 
    https://developer.apple.com/library/mac/#samplecode/NSFontAttributeExplorer/Introduction/Intro.html%23//apple_ref/doc/uid/DTS10003960 
    https://developer.apple.com/library/mac/samplecode/NSFontAttributeExplorer/NSFontAttributeExplorer.zip 
- NSFontManager Class Reference 
    https://developer.apple.com/library/mac/#documentation/Cocoa/Reference/ApplicationKit/Classes/NSFontManager_Class/Reference/Reference.html 
- http://stackoverflow.com/questions/8336693/on-nsrunloop-clarification-needed 
- /System/Library/Frameworks/AppKit.framework/Versions/C/Headers/NSFont.h 


compile with: 
gcc -Wall -Wextra -x objective-c -framework AppKit -o getfonts getfonts.m 

usage: 

./getfonts 

(./getfonts > font.log) & 
pid=$! 
# kill -HUP $pid 


# play around with "Disable selected fonts" & "Enable selected fonts" button 
open -a 'Font Book' 

*/ 


#import <AppKit/AppKit.h> 


// create a counter to avoid createFontList() being called twice for a single font adding/removing event 
// Is there any alternative? 
static int counter = 0; 


@interface FontLogger : NSObject 
{ 
    NSFontManager *mysharedFontManager; 
} 
- (id)init; 
-(void)createFontList; 
@end 


@implementation FontLogger 

- (id)init 
{ 
    if ((self = [super init])) 
    { 
     mysharedFontManager = [NSFontManager sharedFontManager]; 
     [self createFontList]; 
    } 
    return self; 
} 


-(void) setNSFontSetChangedNotification 
{ 
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(fontSetChanged:) name: NSFontSetChangedNotification object: nil]; 
} 

-(void)createFontList 
{ 

    counter = counter + 1; 

    if (counter == 1) 
    { 
     NSString *name = NULL; 
     NSArray *fontarray = [mysharedFontManager availableFonts]; 
     NSEnumerator *nameEnum = [fontarray objectEnumerator]; 

     int i = 0; 
     while ((name = [nameEnum nextObject])) 
     { 
     //NSLog(@"font: %@", name); 
     printf("%s\n", [name UTF8String]); 
     i = i + 1; 
     } 
     printf("Number of available fonts: %i\n\n", i); 
     fflush(stdout); 

    }else { 
     counter = 0; 
    } 

} 

- (void)fontSetChanged:(NSNotification *)notification 
{ 

    if ([[notification name] isEqualToString:@"NSFontSetChangedNotification"]) 
    { 
     [self createFontList]; 
     //NSLog (@"Successfully received notification!"); 
    } 

} 

@end 


int main (void) 
{ 

    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 

    FontLogger *getAvailableFonts = [[[FontLogger alloc] init] autorelease]; 

    [getAvailableFonts setNSFontSetChangedNotification]; 

    BOOL terminated = NO; 

    while(!terminated && [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]]); 

    [pool release]; 

    return 0; 

} 
関連する問題