2009-06-21 2 views
2

в моем проекте Я использую свойствоList для хранения данных. файл plist называется «DataBase.plist». Root for DataBase.plist - это словарь, который содержит 5 словарей в качестве дочерних элементов ... теперь под словарь содержит 4 строки, из которых всегда есть веб-адрес с ключом «URL» (без кавычек) .... i бег следующего кода для извлечения значения для этого ключа URL, но он не работает из ..Чтение ключей NSDictionary из списков свойств

NSString *path = [[NSBundle mainBundle] pathForResource:@"DataBase" ofType:@"plist"]; 
NSDictionary *rootDict = [[NSDictionary alloc] initWithContentsOfFile:path]; 
NSString *URLforAll = [[NSString alloc] init]; 
for (id key in rootDict) 
{ 
    if(key == rowString) 
    { 
     NSDictionary *dict = [rootDict objectForKey:key]; 
     URLforAll = [dict objectForKey:@"URL"]; 
    } 
} 

rowstring является строкой, значение которого совпадает с текстом в выбранной ячейке (я имею протестировал его, это точно). PLease помогите мне, если вы можете .... я буду благодарен

+0

Этот вопрос можно назвать более четко, возможно, «Чтение ключей NSDictionary из файла списка свойств». Это действительно не имеет никакого отношения к ключевому значению кодирования (посмотрите его) и, конечно, ничего особенного для iPhone. Соответственно. –

ответ

3

Попробуйте использовать [key isEqualToString: rowString] вместо сравнения ключей и rowString напрямую с помощью ==. Я думаю, == сравнивает значения указателя объекта, которые не будут равны, даже если строки совпадают.

Также, как и в стороне, вам не нужно инициализировать URLforAll перед его настройкой. Когда вы установите его равным [dict objectForKey:@"URL"], вы потеряете указатель на объект, который вы уже создали, и он будет просочиться. Вместо этого просто скажите NSString *URLforAll = nil; или создать новую строку и autorelease это так, что объект будет автоматически очищен:

NSString * URLforAll = [[[NSString alloc] init] autorelease]; 
+1

Все хорошие предложения. Вы правы, что == сравнивает адреса памяти (указатели). В отличие от C++, Objective-C не поддерживает перегруженные операторы. На самом деле, эта же ошибка вызывает даже разработчиков Java. Сначала я мог бы избежать создания автореализованного объекта - если URLforAll (плохо названный) равен нулю после цикла for, тогда создайте объект. Вероятно, он должен быть только автореализован, если он возвращается из метода. –

+0

FIrst - спасибо тонну за то, что вы помогли --isequalToString отлично работала ..... .... и после этого кода я добавляю [URLforAll release]; вместо использования [[[NSSTring alloc] init] autorelease]; действительно ли память все еще просачивается ... если она скажет мне, как ... , пожалуйста, скажите мне ... а также я где-то читал, что использование autorelease для iphone не предлагается .... и про имя URLofAll it был изменен на вопрос ... спасибо миллион за помощь – valiantb

+1

Вам вообще не нужно выделять/init URLforALl. Просто инициализируйте его до нуля. Возвращаемый метод objectForKey словаря: вы даете вам автореализованный объект. – amrox

2

Вам также не нужно перебрать словарь. Просто спросите его о данных, которые вы хотите.

NSString *path = [[NSBundle mainBundle] pathForResource:@"DataBase" ofType:@"plist"]; 
NSDictionary *rootDict = [[[NSDictionary alloc] initWithContentsOfFile:path] autorelease]; 
NNSString *URLString = [[rootDict objectForKey:key] objectForKey:@"URL"]; 

// do something or return URLString... 
+0

Отличный момент! Если keyString не найден в rootDict, он вернет nil, а внешний objectForKey: не будет иметь никакого эффекта. Man, я люблю обработку Objective-C сообщений до нуля ... :-) –

+0

Фактически, прохождение через словарь необходимо для проекта, зная, что ключевое слово всегда содержит значение .... Большое спасибо за помощь .... .. Спасибо миллиону – valiantb

+1

'[[[[NSDictionary alloc] initWithContentsOfFile: путь] autorelease]' можно записать как '[NSDictionary dictionaryWithContentsOfFile: путь]' – user102008

3

Кроме того, в вашем коде:

NSString *URLforAll = [[NSString alloc] init]; 

Это никогда не делает чувства. Вот некоторые вопросы:

  • Вы выделили объект, который вы затем перезаписываете без изменений URLforAll = [dict objectForKey:@"URL"];. Поэтому вам нужно будет освободить его, прежде чем перезаписывать его.
  • Он выделяется (т. Е. В конце цикла вы «владеете» им и должны его освобождать. Но [dict objectForKey:@"URL"] возвращает объект, который у вас нет. Итак, в конце цикла вы не знаю, владеют ли вы URLforAll или нет.
  • и, наконец, [[NSString alloc] init] никогда не имеет смысла, потому что вы должны просто использовать @"", которая возвращает константу, пустой, NSString, которая непроницаема для retain/release/autorelease вопросов.

Дилинг также с проблемой isEqualToString, но игнорируя гораздо лучшее решение amrox, код будет:

NSString *path = [[NSBundle mainBundle] pathForResource:@"DataBase" ofType:@"plist"]; 
NSDictionary *rootDict = [[NSDictionary alloc] initWithContentsOfFile:path]; 
NSString *URLforAll = @""; 
for (id key in rootDict) { 
     if ([key isEqualToString:rowString]) { 
       NSDictionary *dict = [rootDict objectForKey:key]; 
       URLforAll = [dict objectForKey:@"URL"]; 
     } 
} 
[[URLforAll retain] autorelease]; 
[rootDict release]; 

Обратите внимание, что objectForKey вполне может вернуть внутреннюю ссылку на объект, который станет недействительным, когда вы отпускаете словарь, следовательно, необходимость сохранения объекта, если вы хотите, чтобы держать его дольше, чем жизнь словаря. Использование

amrox по:

NSString *path = [[NSBundle mainBundle] pathForResource:@"DataBase" ofType:@"plist"]; 
NSDictionary *rootDict = [[NSDictionary alloc] initWithContentsOfFile:path]; 
NSString *URLString = [[rootDict objectForKey:key] objectForKey:@"URL"]; 
[[URLString retain] autorelease]; 
[rootDict release]; 
if (!URLString) { 
    URLString = @""; 
} 

является лучшим решением, но вы должны undertand, что случилось с вашим оригинальным решением, а также.

+0

СПАСИБО МИЛЛИОН >>> >>> Я ВАМ ВАС – valiantb

Смежные вопросы