我遇到了我创建的单身人士的问题。它包含两个NSMutableDictionary,它们在整个应用程序中的三个视图(和一些模态视图)中被读取和使用。
我在地图上添加了一个MKMapView,用于绘制字典中的一些场所。当我使用在每个其他视图中使用的完全相同的方法/函数来访问数据时,我收到与解除分配的字典有关的EXC_BAD_ACCESS错误。这来自NSZombieEnabled:
CFDictionary retain: message sent to deallocated instance
在dsym的追踪中,它是用另一个字典取代导致悲伤的字典。我用来调用函数的代码来自MKAnnotationView点击:
UIControl *tempButton = sender;
NSString *selectedEventsString = [self.eventsArray objectAtIndex:tempButton.tag];
NSLog(@"eventString: %@", selectedEventsString);
[[EventsManager eventsManager] changeSelectedEventsDictionaryTo:selectedEventsString];
[tempButton release];
[selectedEventsString release];
“selectedEventsString”将出现一个完全相应的事件。
EventsManager中的相应代码:
-(void)changeSelectedEventsDictionaryTo:(NSString *)eventName {
NSLog(@"singleton: %@", eventName);
self.eventString = eventName;
self.selectedEventsDictionary = [self.eventsDictionary objectForKey:eventName];
}
在.H文件中,selectedEventsDictionary和eventsDictionary都设置为@property(nonatomic,retain),这是init函数:
+ (EventsManager*)eventsManager {
if (eventsManager == nil) {
eventsManager = [[super allocWithZone:NULL] init];
eventsManager.eventsDictionary = [[NSMutableDictionary alloc] init];
eventsManager.selectedEventsDictionary = [[NSMutableDictionary alloc] init];
eventsManager.eventString = [[NSString alloc] init];
eventsManager.mode = [[NSString alloc] init];
}
return eventsManager;
}
这是其他视图中使用的代码示例,可以正常工作:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
NSUInteger row = [indexPath row];
NSString *eventString = [self.eventsArray objectAtIndex:row];
[[EventsManager eventsManager] changeSelectedEventsDictionaryTo:eventString];
//Modal display code here
}
任何帮助将不胜感激!我想我已经提供了所有相关代码,但如果需要更多代码,请告诉我。
干杯!
答案 0 :(得分:1)
从哪里开始!我会指出一些我认为错误的事情。
第一个例子。不要释放tempButton和selectedEventString,因为你从未在它们上显式调用retain / copy或alloc和init。
UIControl *tempButton = sender;
NSString *selectedEventsString = [self.eventsArray objectAtIndex:tempButton.tag];
NSLog(@"eventString: %@", selectedEventsString);
[[EventsManager eventsManager] changeSelectedEventsDictionaryTo:selectedEventsString];
//DO NOT RELEASE THESE YOU NEVER RETAINED THEM!
[tempButton release];
[selectedEventsString release];
您的静态eventsManager不是线程安全的,这对您来说可能不是问题,但是一定要查看。
阅读以下代码示例的注释
+ (EventsManager*)eventsManager {
if (eventsManager == nil) { //<-- Not thread safe
//DO NOT CALL SUPER USE self
//eventsManager = [[self alloc] init];
eventsManager = [[super allocWithZone:NULL] init];
//You need to autorelease these values or use an autoreleased static method
//eventsManager.eventsDictionary = [NSMutableDictionary dictionary];
//eventsManager.selectedEventsDictionary = [NSMutableDictionary dictionary];
eventsManager.eventsDictionary = [[NSMutableDictionary alloc] init];
eventsManager.selectedEventsDictionary = [[NSMutableDictionary alloc] init];
//Do not bother setting these at all or just set them to nil
eventsManager.eventString = [[NSString alloc] init];
eventsManager.mode = [[NSString alloc] init];
}
return eventsManager;
}
确保将所有这些属性设置为保留或复制,这可能会解决您的问题。如果您在修复这些问题后仍有问题,可以更新您的问题,我会更新我的答案。