Приложение зависает в iOS7, но не в 8 и 9 из-за автоматического выпуска NSDictionary
+ (NSString *)getValueforLocale:(NSString*) i18nkey :(NSString*)locale{
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES);
NSLog(@"paths are : %@",paths);
NSString *libraryDirectory = [paths objectAtIndex:0];
NSLog(@"libraryDirectory : %@",libraryDirectory);
NSString *filePath = [libraryDirectory stringByAppendingPathComponent:@"I8nDB"];
filePath = [filePath stringByAppendingPathComponent:locale];
NSLog(@"file path is : %@",filePath);
BOOL fileExists = [[NSFileManager defaultManager] fileExistsAtPath:filePath];
if(fileExists)
{
NSDictionary *dict = [[[NSDictionary alloc] initWithContentsOfFile:filePath]autorelease];
NSDictionary *resourceBundle = [[[NSDictionary alloc] init]autorelease];
NSString *keyValue = [[[NSString alloc]init]autorelease];
resourceBundle = [dict valueForKey:@"hash"];
keyValue=[resourceBundle valueForKey:i18nkey];
NSLog(@"value for %@ is(container) : %@",i18nkey,keyValue);
if(keyValue != nil || keyValue != NULL)
{
return keyValue;
}
else
{
NSLog(@"key not found in the container file");
NSString *path = [[NSBundle mainBundle] pathForResource:@"Localizable"
ofType:@"strings"
inDirectory:nil
forLocalization:locale];
NSLog(@"path for %@ is : %@",locale,path);
fileExists = [[NSFileManager defaultManager] fileExistsAtPath:path];
if(fileExists)
{
NSDictionary *dict = [[NSDictionary dictionaryWithContentsOfFile:path]autorelease];
NSLog(@"value for %@ is(resources) : %@",i18nkey,[dict objectForKey:i18nkey]);
return [dict objectForKey:i18nkey];
}
else
{
return NULL;
}
}
}
else
{
NSLog(@"%@ locale does not exist in container",locale);
NSString *path = [[NSBundle mainBundle] pathForResource:@"Localizable"
ofType:@"strings"
inDirectory:nil
forLocalization:locale];
NSLog(@"path for %@ in resources is : %@",locale,path);
fileExists = [[NSFileManager defaultManager] fileExistsAtPath:path];
if(fileExists)
{
NSDictionary *dict = [[NSDictionary dictionaryWithContentsOfFile:path]autorelease];
NSLog(@"value for %@ is : %@",i18nkey,[dict objectForKey:i18nkey]);
return [dict objectForKey:i18nkey];
}
else
{
return NULL;
}
}
}
Если мы удалим Autorelease из приведенного выше кода, он работает в iOS7, если не происходит сбой приложения
Моя главная проблема заключается в том, почему не происходит сбой в iOS8 и 9, а происходит только сбой в iOS7, есть изменения, связанные с автоматическим выпуском в этих версиях
3 ответа
Почему вы не используете ARC? Тогда вам не понадобится autorelease
... См. http://rypress.com/tutorials/objective-c/memory-management
Ваша проблема может быть связана с настройками о ARC.
При ручном подсчете ссылок удержания и выпуски должны быть сбалансированы.
В
NSDictionary *dict = [[[NSDictionary alloc] initWithContentsOfFile:filePath]autorelease];
NSDictionary *resourceBundle = [[[NSDictionary alloc] init]autorelease];
удержания и выпуски сбалансированы, потому что alloc
(вместе с retain
, new
, copy
, mutableCopy
) возвращает сохраненный экземпляр и autorelease
считается как release
,
Однако в
NSDictionary *dict = [[NSDictionary dictionaryWithContentsOfFile:path]autorelease];
у вас есть перевыпуск, потому что вы autorelease
то, что вы не сохранили.
Версия для iOS не имеет к этому никакого отношения.
В вашем коде вы размещаете только словарь
NSDictionary *dict = [[NSDictionary alloc] initWithContentsOfFile:filePath];
так что вам нужно только позаботиться об этом, другой объект не принадлежит вам! поэтому вам не нужно выпускать или автоматически выпускать их.
Попробуйте текущий код
+ (NSString *)getValueforLocale:(NSString*) i18nkey :(NSString*)locale
{
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES);
NSLog(@"paths are : %@",paths);
NSString *libraryDirectory = [paths objectAtIndex:0];
NSLog(@"libraryDirectory : %@",libraryDirectory);
NSString *filePath = [libraryDirectory stringByAppendingPathComponent:@"I8nDB"];
filePath = [filePath stringByAppendingPathComponent:locale];
NSLog(@"file path is : %@",filePath);
BOOL fileExists = [[NSFileManager defaultManager] fileExistsAtPath:filePath];
if(fileExists)
{
NSDictionary *dict = [[NSDictionary alloc] initWithContentsOfFile:filePath];
//NSDictionary *resourceBundle = [[[NSDictionary alloc] init]autorelease];
//NSString *keyValue = [[[NSString alloc]init]autorelease];
NSDictionary *resourceBundle = [dict valueForKey:@"hash"];
// relese dict here because not use after
[dict release];
NSString *keyValue=[resourceBundle valueForKey:i18nkey];
NSLog(@"value for %@ is(container) : %@",i18nkey,keyValue);
if(keyValue != nil || keyValue != NULL)
{
return keyValue;
}
else
{
NSLog(@"key not found in the container file");
NSString *path = [[NSBundle mainBundle] pathForResource:@"Localizable"
ofType:@"strings"
inDirectory:nil
forLocalization:locale];
NSLog(@"path for %@ is : %@",locale,path);
fileExists = [[NSFileManager defaultManager] fileExistsAtPath:path];
if(fileExists)
{
// NSDictionary *dict = [[NSDictionary dictionaryWithContentsOfFile:path]autorelease];
NSDictionary *dict = [NSDictionary dictionaryWithContentsOfFile:path];
NSLog(@"value for %@ is(resources) : %@",i18nkey,[dict objectForKey:i18nkey]);
return [dict objectForKey:i18nkey];
}
else
{
return NULL;
}
}
}
else
{
NSLog(@"%@ locale does not exist in container",locale);
NSString *path = [[NSBundle mainBundle] pathForResource:@"Localizable"
ofType:@"strings"
inDirectory:nil
forLocalization:locale];
NSLog(@"path for %@ in resources is : %@",locale,path);
fileExists = [[NSFileManager defaultManager] fileExistsAtPath:path];
if(fileExists)
{
// NSDictionary *dict = [[NSDictionary dictionaryWithContentsOfFile:path]autorelease];
NSDictionary *dict = [NSDictionary dictionaryWithContentsOfFile:path];
NSLog(@"value for %@ is : %@",i18nkey,[dict objectForKey:i18nkey]);
return [dict objectForKey:i18nkey];
}
else
{
return NULL;
}
}
}