Я застрял на нем уже более недели и, по-видимому, никто не сообщил об этой проблеме ранее в stackoverflow. Пожалуйста, внимательно прочитайте мое описание, прежде чем обращаться ко мне с другими сообщениями, потому что я прочитал их все, и никто из них не получил моего ответа.- [__ NSDictionaryI isNSString__]: сообщение отправлено на освобожденный экземпляр
У меня есть NSDictionary, содержащий NSNumber и NSArray из NSStrings, причем оба ключа являются NSStrings.
Теперь NSDictionary WriteToFile падает с ошибкой: - [NSDictionaryI isNSString]: сообщение, отправленное высвобождены например
WriteToFile вызывается метод класса, как, например:
@implementation AppDataStore
+ (void) saveData:(NSDictionary*)dataDictionary {
NSArray *directories = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documents = [directories firstObject];
NSString *appDataFilePath = [documents stringByAppendingPathComponent:@"AppDataStore.plist"];
[dataDictionary writeToFile:appDataFilePath atomically:YES];
}
Следует отметить, что я Я передаю метод NSMutableDictionary для этого метода, но это не проблема, потому что он записывает другие значения ключа NSMutableDictionaries просто отлично, но не содержит тот, который содержит NSArray. Даже когда я вынимаю элемент NSNumber, поэтому словарь содержит только NSArray, writeToFile все равно выдает ту же ошибку. Сбой как на симуляторе, так и на iPhone.
Что происходит ?!
EDIT 1 (в ответ на вопрос Адама):
стека не проследить вплоть до прямо перед аварией:
Stack trace : (
0 MedList 0x00009b39 +[AppDataStore saveData:] + 217
1 MedList 0x0000811d -[ViewController tableView:didSelectRowAtIndexPath:] + 1101
2 UIKit 0x010c894c -[UITableView _selectRowAtIndexPath:animated:scrollPosition:notifyDelegate:] + 1559
3 UIKit 0x010c8af7 -[UITableView _userSelectRowAtPendingSelectionIndexPath:] + 285
4 UIKit 0x010cddf3 __38-[UITableView touchesEnded:withEvent:]_block_invoke + 43
5 UIKit 0x00fe20ce ___afterCACommitHandler_block_invoke + 15
6 UIKit 0x00fe2079 _applyBlockToCFArrayCopiedToStack + 415
7 UIKit 0x00fe1e8e _afterCACommitHandler + 545
8 CoreFoundation 0x00b289de __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 30
9 CoreFoundation 0x00b28920 __CFRunLoopDoObservers + 400
10 CoreFoundation 0x00b1e35a __CFRunLoopRun + 1226
11 CoreFoundation 0x00b1dbcb CFRunLoopRunSpecific + 443
12 CoreFoundation 0x00b1d9fb CFRunLoopRunInMode + 123
13 GraphicsServices 0x03efd24f GSEventRunModal + 192
14 GraphicsServices 0x03efd08c GSEventRun + 104
15 UIKit 0x00fb88b6 UIApplicationMain + 1526
16 MedList 0x0000681d main + 141
17 libdyld.dylib 0x02f6bac9 start + 1
18 ??? 0x00000001 0x0 + 1
)
2015-02-16 21:39:37.762 MedList[14029:496685] *** -[__NSDictionaryI isNSString__]: message sent to deallocated instance 0x7974e910
EDIT 2: Я сделал еще несколько тестов. NSDictionary внутри моего NSArray получает освобождение ПЕРЕД вызовом метода класса (до writeToFile) и только AFTER didSelectRowAtIndexPath. Почему выбор строки таблицы автоматически освобождает словарь, содержащийся внутри массива? Это странное поведение. Есть предположения?
У вас есть трассировки стека? – AdamPro13
Мы уверены, что это NSDictionary, который терпит неудачу, так как это класс, который появляется в сообщении. (Он мог быть освобожден как нечто другое, а затем перераспределено, поскольку NSDicitonary затем снова освобождается, но это кажется маловероятным.) Однако мы не знаем, является ли он самым внешним словарем или «внутренним», внутри 'dataDictionary'. Если можно было бы остановиться, когда возникла ошибка, и поместите отладчик в стек стека 'saveData' и сделайте' po dataDictionary', тогда он должен сбросить объект, и у вас будет ключ к вопросу о том, исчезло ли оно или что-то в нем , –
Я признаю, что раньше такого отладки не делал. Можете ли вы опубликовать пару скриншотов, которые показывают, как это сделать? Я провел мое исследование по po (print-object), до сих пор безрезультатно. –