我有一个奇怪的问题:当我在我的应用程序中更改语言时,一切似乎都没问题,但有时当我连续执行4次以上时,我有一个错误:2014年 -
05-31 18:13:46.304 MobileControl[1173:a72f] CRASH:
<MKMapView: 0x18fe7840; frame = (0 0; 0 0); transform = [0, 0, 0, 0, 0, 0]; alpha = 0; opaque = NO; layer = (null)> initWithCoder:: MKMapView must be initialized on the main thread.
2014-05-31 18:13:46.372 MobileControl[1173:a72f] Stack Trace:
(
0 CoreFoundation 0x2f02cfeb <redacted> + 154
1 libobjc.A.dylib 0x39d03ccf objc_exception_throw + 38
2 CoreFoundation 0x2f02cf15 <redacted> + 0
3 MapKit 0x301facb1 <redacted> + 1228
4 UIKit 0x31c5d171 <redacted> + 740
5 UIKit 0x31c5ce87 <redacted> + 90
6 UIKit 0x31bb85e1 <redacted> + 112
7 UIKit 0x31c5d171 <redacted> + 740
8 UIKit 0x31c5d111 <redacted> + 644
9 UIKit 0x31c5ce87 <redacted> + 90
10 UIKit 0x31bb7dd9 <redacted> + 888
11 UIKit 0x31b1062b <redacted> + 234
12 UIKit 0x3196cbed <redacted> + 92
13 UIKit 0x3184d30d <redacted> + 72
14 UIKit 0x318f7c01 <redacted> + 32
15 UIKit 0x318f7b17 <redacted> + 230
16 UIKit 0x318f70f3 <redacted> + 78
17 UIKit 0x318f6e1d <redacted> + 572
18 UIKit 0x318f6b8d <redacted> + 44
19 UIKit 0x318f6b25 <redacted> + 184
20 UIKit 0x31848d79 <redacted> + 380
21 QuartzCore 0x314c662b <redacted> + 142
22 QuartzCore 0x314c1e3b <redacted> + 350
23 QuartzCore 0x314c1ccd <redacted> + 16
24 QuartzCore 0x314c16df <redacted> + 230
25 QuartzCore 0x314c14ef <redacted> + 314
26 QuartzCore 0x314eea83 <redacted> + 162
27 libsystem_pthread.dylib 0x3a32e68d <redacted> + 164
28 libsystem_pthread.dylib 0x3a32e40b <redacted> + 86
29 libsystem_pthread.dylib 0x3a32f17d pthread_exit + 28
30 Foundation 0x2f96946f <redacted> + 10
31 Foundation 0x2fa15a7d <redacted> + 1092
32 libsystem_pthread.dylib 0x3a32f919 <redacted> + 140
33 libsystem_pthread.dylib 0x3a32f88b _pthread_start + 102
34 libsystem_pthread.dylib 0x3a32daa4 thread_start + 8
)
2014-05-31 18:13:46.378 MobileControl[1173:a72f] *** Terminating app due to uncaught exception 'NSRangeException', reason: '<MKMapView: 0x18fe7840; frame = (0 0; 0 0); transform = [0, 0, 0, 0, 0, 0]; alpha = 0; opaque = NO; layer = (null)> initWithCoder:: MKMapView must be initialized on the main thread.'
*** First throw call stack:
(0x2f02cfd3 0x39d03ccf 0x2f02cf15 0x301facb1 0x31c5d171 0x31c5ce87 0x31bb85e1 0x31c5d171 0x31c5d111 0x31c5ce87 0x31bb7dd9 0x31b1062b 0x3196cbed 0x3184d30d 0x318f7c01 0x318f7b17 0x318f70f3 0x318f6e1d 0x318f6b8d 0x318f6b25 0x31848d79 0x314c662b 0x314c1e3b 0x314c1ccd 0x314c16df 0x314c14ef 0x314eea83 0x3a32e68d 0x3a32e40b 0x3a32f17d 0x2f96946f 0x2fa15a7d 0x3a32f919 0x3a32f88b 0x3a32daa4)
libc++abi.dylib: terminating with uncaught exception of type NSException
虽然一切都与MKMapView相关,我在主线程中做了什么。
我知道这种情况并不常见,正常的应用用户在几秒钟内没有超过4次更改语言,但它仍然给我一个错误。
更改语言:
Settings.m:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[self.TableViewLanguage deselectRowAtIndexPath:indexPath animated:YES];
switch (indexPath.row)
{
case kLANG_HEB:
userLang = kHEB;
[defaults setObject:@[@"he", @"en"] forKey:@"AppleLanguages"];
break;
case kLANG_ENG:
userLang = kENG;
[defaults setObject:@[@"en", @"he"] forKey:@"AppleLanguages"];
break;
case kLANG_RUS:
userLang = kRUS;
[defaults setObject:@[@"ru", @"en"] forKey:@"AppleLanguages"];
break;
case kLANG_ARAB:
userLang = kARAB;
[defaults setObject:@[@"ar", @"en"] forKey:@"AppleLanguages"];
break;
case kLANG_FRA:
userLang = kFRA;
[defaults setObject:@[@"fr", @"en"] forKey:@"AppleLanguages"];
}
[defaults setValue:userLang forKey:@"language"];
[defaults setBool:YES forKey:ComeFromChangeLang];
[defaults synchronize];
if ([appDelegate.window.rootViewController isKindOfClass:[SplashScreen class]]) {
[self.navigationController popToRootViewControllerAnimated:YES];
}
else {
SplashScreen *viewController = [self.storyboard instantiateViewControllerWithIdentifier:@"ViewController"];
UINavigationController *nc = [[UINavigationController alloc] initWithRootViewController:viewController];
MainMap *mapViewController = [self.storyboard instantiateViewControllerWithIdentifier:@"MainAppScreen"];
mapViewController.mapView.delegate = nil;
dispatch_async(dispatch_get_main_queue(), ^{
appDelegate.window.rootViewController = nc;
[appDelegate.window makeKeyAndVisible];
});
}
}
处理地图:
MainMap.m:
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
defaults = [NSUserDefaults standardUserDefaults];
self.navigationController.navigationBarHidden = NO;
[self initSidePanel];
self.navigationItem.title = NSLocalizedString(@"my_location", nil);
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(popToRootViewController:)
name:kPopToRootViewController
object:nil];
if (__iOS_7_And_Heigher) {
CGRect frame = self.btnCenterLocation.frame;
frame.origin.y += 12;
self.btnCenterLocation.frame = frame;
}
[defaults removeObjectForKey:@"TEMPORARY_MOBILE"];
[defaults removeObjectForKey:@"userPassword"];
[defaults setBool:NO forKey:kLogoutKey];
[defaults synchronize];
[SVProgressHUD dismiss];
if ([CLLocationManager locationServicesEnabled]) {
[self initMainMap];
}
}
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
if ([self.navigationController.navigationBar respondsToSelector:@selector(setBarTintColor:)]) {
[self.navigationController.navigationBar setBarTintColor:OrangeOfficialColor];
[self.navigationController.navigationBar setTintColor:[UIColor whiteColor]];
} else {
[self.navigationController.navigationBar setTintColor:OrangeOfficialColor];
}
}
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
if ([CLLocationManager locationServicesEnabled]) {
dispatch_async(dispatch_get_main_queue(), ^{
self.mapView.mapType = [self getMapType];
});
}
else {
if (!self.alertView.isVisible) {
if ([CLLocationManager authorizationStatus] == kCLAuthorizationStatusDenied ||
[CLLocationManager authorizationStatus] == kCLAuthorizationStatusRestricted) {
self.alertView = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"mobile_control_team", nil) message:NSLocalizedString(@"gps_and_wifi_text", nil) delegate:self cancelButtonTitle:NSLocalizedString(@"ok", nil) otherButtonTitles:nil];
self.alertView.tag = kTagAlertViewNoLocation;
[self.alertView show];
}
}
}
}
- (void)initMainMap
{
dispatch_async(dispatch_get_main_queue(), ^{
self.mapView.delegate = self;
self.mapView.mapType = [self getMapType];
self.mapView.userInteractionEnabled = YES;
self.mapView.userTrackingMode = MKUserTrackingModeFollow;
self.mapView.showsUserLocation = YES;
[self centerCurrentLocation:self.mapView.userLocation];
});
[[SplashScreen sharedScreen] restartService];
}
#pragma mark -
#pragma mark - MKMapView Delegate
/****************************************************************************/
/* MKMapView Delegate */
/****************************************************************************/
- (void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation
{
@try {
if ([CLLocationManager authorizationStatus] != kCLAuthorizationStatusAuthorized) {
return;
}
if (userLocation.location == nil) {
return;
}
// Work around a bug in MapKit where user location is not initially zoomed to.
if (userLocation.coordinate.latitude != 0.0 && userLocation.coordinate.longitude != 0.0) {
MKCoordinateRegion userRegion = MKCoordinateRegionMakeWithDistance(userLocation.coordinate, 1500.0, 1500.0);
dispatch_async(dispatch_get_main_queue(), ^{
[mapView setRegion:userRegion animated:YES];
});
}
}
@catch (NSException *exception) {
NSLog(@"%s, exception.reason: %@", __PRETTY_FUNCTION__, exception.reason);
}
}
- (void)mapView:(MKMapView *)mapView didFailToLocateUserWithError:(NSError *)error
{
NSLog(@"%s, %@", __PRETTY_FUNCTION__, error.localizedDescription);
}
- (void)gotoLocation
{
MKCoordinateRegion newRegion;
newRegion.center.latitude = _locationManager.location.coordinate.latitude;
newRegion.center.longitude = _locationManager.location.coordinate.longitude;
newRegion.span.latitudeDelta = 0.112872;
newRegion.span.longitudeDelta = 0.109863;
dispatch_async(dispatch_get_main_queue(), ^{
[self.mapView setRegion:newRegion animated:YES];
});
}
- (MKMapType)getMapType
{
NSLog(@"%s, [defaults integerForKey:@\"map_mode\"]: %ld", __PRETTY_FUNCTION__, (long)[defaults integerForKey:@"map_mode"]);
switch ([defaults integerForKey:@"map_mode"]) {
case 0:
case 1:
return MKMapTypeStandard;
case 2:
return MKMapTypeSatellite;
case 3:
return MKMapTypeHybrid;
default:
return MKMapTypeStandard;
}
}
我似乎无法找到我的问题,我只是在主线程中触摸MKMapView但我仍然会收到此错误,不知道吗?
编辑1:
SplashScreen.m:
- (void)restartService
{
self.locationTracker = [[LocationTracker alloc]init];
[self.locationTracker performSelectorOnMainThread:@selector(startService) withObject:nil waitUntilDone:NO];
}
LocationTracker.m:
- (void)startService
{
NSLog(@"%s", __PRETTY_FUNCTION__);
if (![CLLocationManager locationServicesEnabled]) { // Location services disabled
NSLog(@"locationServices not enabled.");
if ([CLLocationManager authorizationStatus] == kCLAuthorizationStatusDenied ||
[CLLocationManager authorizationStatus] == kCLAuthorizationStatusRestricted) { // User choosed not to use location
NSLog(@"locationServices not authorized.");
dispatch_async(dispatch_get_main_queue(), ^{
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"mobile_control_team", nil)
message:NSLocalizedString(@"gps_and_wifi_text", nil)
delegate:self
cancelButtonTitle:NSLocalizedString(@"ok", nil)
otherButtonTitles:nil];
[alertView show];
});
}
return;
}
if ([CLLocationManager authorizationStatus] != kCLAuthorizationStatusAuthorized) {
NSLog(@"user not authorized to use locationServices.");
[self performSelector:@selector(startService) withObject:nil afterDelay:30];
}
if ([defaults integerForKey:@"userID"] <= 0) {
NSLog(@"Incorrect userID: %li", (long)[defaults integerForKey:@"userID"]);
return;
}
[MobileControlHandler clearMyInfoData];
_isFiveMinutesTimer = NO;
_fiveMinutesTimer = 0;
_serviceWillStop = NO;
_operationQueue = [NSOperationQueue new];
_internetOpsQueue = [NSOperationQueue new];
[_operationQueue addObserver:self
forKeyPath:@"operationCount"
options:0
context:NULL];
[_internetOpsQueue addObserver:self
forKeyPath:@"operationCount"
options:0
context:nil];
self.isSameLocation = NO;
self.measuredLocations = [[NSMutableArray alloc] init];
///
[self startLocationTracking];
///
if ([CLLocationManager locationServicesEnabled]) {
[self performSelector:@selector(startServiceListener) withObject:nil afterDelay:3];
[self startTimerCounter];
}
}
+ (void)stopService
{
[LocationTracker sharedLocationManager].delegate = nil;
CFRunLoopStop(CFRunLoopGetCurrent());
[self cancelPreviousPerformRequestsWithTarget:self selector:@selector(startServiceListener) object:nil];
}
- (void)startTimerCounter
{
timerTask = [[NSTimerTask alloc] init];
[timerTask scheduleTimerTaskInterval:TimerTaskIntervalMinutes timeValue:1 usingBlock:^{
[self timerTaskInterval];
}];
}
- (void)timerTaskInterval
{
NSLog(@"%s", __PRETTY_FUNCTION__);
if (isStandingOperation == true) {
if (userCycleFiveTimes < 5) {
userCycleFiveTimes++;
isStandingOperation = true;
[self startServiceListener];
}
else if (userCycleFiveTimes == 5) {
counter = 0;
userCycleFiveTimes = 0;
isStandingOperation = false;
}
}
else if (isStandingOperation == false) {
counter++;
if (counter == 1 || counter == 2 || counter == 4) {
[self startServiceListener];
}
else if (counter == 8) {
counter = 0;
eightHowManyTimesCounter++;
[self startServiceListener];
}
}
if (eightHowManyTimesCounter == 2) {
eightHowManyTimesCounter = 0;
[self saveLocation];
}
[timerTask scheduleTimerTaskInterval:TimerTaskIntervalMinutes timeValue:1 usingBlock:^{
[self timerTaskInterval];
}];
}
- (void)startServiceListener
{
if (![CLLocationManager locationServicesEnabled]) {
NSLog(@"locationServices not enabled.");
return;
}
if ([CLLocationManager authorizationStatus] != kCLAuthorizationStatusAuthorized) {
NSLog(@"user not authorized to use locationServices.");
return;
}
if (measuredLocations.count > 2) {
NSInteger lastObjectIndex = measuredLocations.count - 1;
NSInteger oneBeforeLastObjectIndex = lastObjectIndex - 1;
CLLocation *locLast = measuredLocations[lastObjectIndex];
CLLocation *locBeforeLast = measuredLocations[oneBeforeLastObjectIndex];
if (locLast.coordinate.latitude == locBeforeLast.coordinate.latitude &&
locLast.coordinate.longitude == locBeforeLast.coordinate.longitude) {
NSLog(@"----------SAME ADDRESS!----------");
self.isSameLocation = YES;
if (self.measuredLocations.count >= 20) {
self.measuredLocations = [[NSMutableArray alloc] init];
self.isSameLocation = NO;
}
}
else {
self.isSameLocation = NO;
}
}
if (!self.isSameLocation) {
// NSLog(@"Different location.");
[self saveLocation];
}
else {
NSLog(@"Same location.");
}
[self performGetCloud];
// GetCloud only if we don't have token (Apple push notification unique id per device)
/*if ([defaults boolForKey:IS_TOKEN_OK] == NO || [UIDevice currentDevice].systemVersion.floatValue < 7.1) {
[self performGetCloud];
}*/
}