3

我们将很多字体与我们的 iOS 应用程序捆绑在一起,并将它们全部放入UIAppFonts以加快加载速度。
(我们在内部使用它们UIWebView,它比使用加载文件快得多@font-face

然而,这导致我偶尔会收到这种警告:

Mar 13 23:07:16 iPad afcd[2582] <Error>: Max open files: 78
Mar 13 23:07:17 iPad mobile_house_arrest[2584] <Error>: Max open files: 78
Mar 13 23:07:17 iPad mobile_house_arrest[2586] <Error>: Max open files: 78
Mar 13 23:07:17 iPad mobile_house_arrest[2587] <Error>: Max open files: 78
Mar 13 23:07:17 iPad mobile_house_arrest[2588] <Error>: Max open files: 78

这也与打开文件时的 I/O 异常有关。

我使用这个片段来找出泄漏的文件,看起来 iOS 在应用程序的整个生命周期中为列出的每种字体保留了打开的文件描述符UIAppFonts

File Descriptor 8 number 9 in use for: Fonts/ABeeZee-Regular.ttf
File Descriptor 9 number 10 in use for: Fonts/ABeeZee-Regular.ttf
File Descriptor 10 number 11 in use for: Fonts/ABeeZee-Italic.ttf
File Descriptor 11 number 12 in use for: Fonts/ABeeZee-Italic.ttf
File Descriptor 12 number 13 in use for: Fonts/AmaticSC-Regular.ttf
File Descriptor 13 number 14 in use for: Fonts/AmaticSC-Regular.ttf
File Descriptor 14 number 15 in use for: Fonts/AmaticSC-Bold.ttf
File Descriptor 15 number 16 in use for: Fonts/AmaticSC-Bold.ttf
File Descriptor 16 number 17 in use for: Fonts/AnonymousPro-Bold.ttf
File Descriptor 17 number 18 in use for: Fonts/AnonymousPro-Bold.ttf
File Descriptor 18 number 19 in use for: Fonts/AnonymousPro-Regular.ttf
File Descriptor 19 number 20 in use for: Fonts/AnonymousPro-Regular.ttf

对我们来说,这意味着大约有一百个打开的文件描述符,尽管UIAppFonts目前使用的不超过五个。有时,会出现重复的条目。

UIAppFonts是否有强制关闭我目前不使用的文件描述符?

如果没有,是否有另一种方法可以保持本地字体可用,UIWebView而无需求助于@font-face哪种方法很慢?

4

2 回答 2

2

如果没有,是否有另一种方法可以使 UIWebView 可以使用本地字体,而无需诉诸 @font-face 这很慢?

原来,有。

我们通过使用注册字体CTFontManagerRegisterFontsForURL和使用取消注册字体解决了这个问题CTFontManagerUnregisterFontsForURL。这使它们可用于UIWebView,因为您总是在使用它们之前注册字体font-family

于 2013-04-15T15:50:23.723 回答
1

我在关闭与 Sprite Kit 操作关联的文件描述符时遇到问题,

playSoundFileNamed:

他们从不关闭。所以他们吃掉了文件描述符,直到应用程序崩溃。我想出了一个关闭它们的方法。我不明白为什么它不适用于您的 UIAppFonts。

我修改了您在问题中引用的代码段。这是我的修改版,

#import <sys/types.h>
#import <fcntl.h>
#import <errno.h>
#import <sys/param.h>


-(void)closeFileDescriptorsForSounds
{
    int flags;
    int fd;
    char buf[MAXPATHLEN+1] ;
    int n = 1 ;

    for (fd = 0; fd < (int) FD_SETSIZE; fd++) {
        errno = 0;
        flags = fcntl(fd, F_GETFD, 0);
        if (flags == -1 && errno) {
            if (errno != EBADF) {
                return ;
            }
            else
                continue;
        }
        fcntl(fd , F_GETPATH, buf ) ;
        NSLog( @"File Descriptor %d number %d in use for: %s",fd,n , buf ) ;
        ++n ;

// My modifications to the snippet...

        NSString *str = [NSString stringWithUTF8String:buf];
        NSString *theFileName = [str lastPathComponent];

        if ([theFileName isEqualToString:@"LoudBang.mp3"])
        {
            NSLog(@"FD is LoudBang");
            NSFileHandle *loudBangHandle = [[NSFileHandle alloc] initWithFileDescriptor:fd closeOnDealloc:YES];
        }
        else if ([theFileName isEqualToString:@"QuietBang.mp3"])
        {
            NSLog(@"FD is QuietBang");
            NSFileHandle *quietBangHandle = [[NSFileHandle alloc] initWithFileDescriptor:fd closeOnDealloc:YES];
        }
    }
}

我将 buf 转换为字符串,然后隔离文件名。然后我将文件名与我要关闭的已知文件进行了比较。当找到我要关闭的文件时,代码使用以下内容在文件描述符周围创建一个 NSFileHandle,

NSFileHandle *loudBangHandle = [[NSFileHandle alloc] initWithFileDescriptor:fd closeOnDealloc:YES];

这个 init 专门关闭了 NSFileHandle 的 dealloc 上的文件描述符(几乎立即关闭)。

让我们知道它是否适用于您的 UIAppFonts。

于 2015-01-04T02:09:55.017 回答