问题
We bundle a lot of fonts with our iOS app, and we put them all in UIAppFonts
for faster loading.
(We're using them inside UIWebView
and it's much faster than using loading files with @font-face
).
However this lead me to occasionally get this kind of warning:
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
This also correlated with I/O exceptions when opening files.
I used this snippet to find out the leaking files and it looks like iOS keeps open file descriptors for every font listed in UIAppFonts
throughout the whole lifetime of the application.
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
For us, it means about a hundred open file descriptors, although not more than five of UIAppFonts
are being used at the moment. Sometimes, duplicate entries show up.
Is there anyway to forcibly close file descriptors for UIAppFonts
I'm not using at the moment?
If not, is there an alternative way of keeping local fonts available to UIWebView
without resorting to @font-face
which is slow?
回答1:
If not, is there an alternative way of keeping local fonts available to UIWebView without resorting to @font-face which is slow?
Turns out, there is.
We solved the problem by registering fonts using CTFontManagerRegisterFontsForURL and unregistering them with CTFontManagerUnregisterFontsForURL. This keeps them available for UIWebView
, given that you always register fonts before using them in font-family
.
回答2:
I was having trouble with closing file descriptors associated with a Sprite Kit action,
playSoundFileNamed:
They never close. So they eat up file descriptors until the app crashes. I figured out a way to close them. I don't see why it wouldn't work for your UIAppFonts.
I modified the snippet you referenced in your question. This is my modified version,
#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];
}
}
}
I converted buf to a string and then isolated the file name. Then I compared the file name to a known file I want to close. When a file I want to close is found the code creates an NSFileHandle around the file descriptor using the following,
NSFileHandle *loudBangHandle = [[NSFileHandle alloc] initWithFileDescriptor:fd closeOnDealloc:YES];
This init specifically closes the file descriptor on dealloc of the NSFileHandle (which will be almost immediately).
Let us know if it works for your UIAppFonts.
来源:https://stackoverflow.com/questions/15397573/can-i-close-file-descriptors-for-currently-unused-uiappfonts