I'm having trouble with CoreLocation region delegate methods in iOS 5, both in simulator and on devices. I'm trying to add a region for monitoring, and then waiting for the didStartMonitoring delegate callback. Rarely, it works fine. However, usually neither didStartMonitoring nor monitoringDidFail get called. The region does get added to monitoredRegions. The delegate object is set correctly, and usually gets calls for didEnterRegion and didExitRegion. The location manager is never released. This is on the main thread. I've checked all the conditions I can think of.
-(id) init
{
   self = [super init];
   if( self ) {
      NSLog( @"initializing location manager" );
      self.locationManager = [[CLLocationManager alloc] init];
      locationManager.delegate = self;
      [locationManager startUpdatingLocation];
   }
   return self;
}
-(void) startMonitoringRegion
{
   BOOL monitoring = NO;    
   if ( [CLLocationManager regionMonitoringAvailable] ) {
      if ( [CLLocationManager regionMonitoringEnabled] ) {
         if( [CLLocationManager authorizationStatus] == kCLAuthorizationStatusAuthorized ) {
            monitoring = YES;
         } else {
            NSLog( @"app is not authorized for location monitoring" );
         }
      } else {
         NSLog( @"region monitoring is not enabled" );
      }
   } else {
      NSLog( @"region monitoring is not available" );
   }
   if( !monitoring ) return;
   CLRegion *region = [[CLRegion alloc] initCircularRegionWithCenter:locationManager.location.coordinate 
                                                          radius:50
                                                      identifier:@"majorRegion"];
   NSLog( @"trying to start monitoring for region %@", region );
   [locationManager startMonitoringForRegion:region desiredAccuracy:kCLLocationAccuracyBest];
}
-(void)     locationManager:(CLLocationManager*)manager 
didStartMonitoringForRegion:(CLRegion*)region
{
   NSLog( @"region monitoring started" );
}
- (void)   locationManager:(CLLocationManager *)manager
monitoringDidFailForRegion:(CLRegion *)region 
                 withError:(NSError *)error
{
   NSLog( @"region monitoring failed" );
}
- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error
{
   NSLog( @"location manager failed" );
}
Anybody have any ideas? I can handle this, but it appears that the didEnterRegion and didExitRegion delegate methods are also sometimes inconsistent, and that's a big problem for me.
Edit: I can replicate this functionality within a single app delegate -- no custom objects or anything. See implementation below. The regions get added (seen when printed), but didStartMonitoringRegion never gets called.
@implementation AppDelegate
@synthesize window = _window;
@synthesize locationManager;
-(void) startMonitoringRegion
{
   BOOL monitoring = NO;    
   if ( [CLLocationManager regionMonitoringAvailable] ) {
      if ( [CLLocationManager regionMonitoringEnabled] ) {
         if( [CLLocationManager authorizationStatus] == kCLAuthorizationStatusAuthorized )  {
            monitoring = YES;
         } else {
            NSLog( @"app is not authorized for location monitoring" );
         }
      } else {
         NSLog( @"region monitoring is not enabled" );
      }
   } else {
      NSLog( @"region monitoring is not available" );
   }
   if( !monitoring ) return;
   CLRegion *region = [[CLRegion alloc] initCircularRegionWithCenter:locationManager.location.coordinate 
                                                              radius:50.
                                                          identifier:@"majorRegion"];
   NSLog( @"trying to start monitoring for region %@", region );
   [locationManager startMonitoringForRegion:region desiredAccuracy:kCLLocationAccuracyBest];
}
-(void) printMonitoredRegions
{
   NSLog( @"printing regions:" );
   for( CLRegion* region in locationManager.monitoredRegions )
      NSLog( @"%@", region );
}
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
   NSLog( @"initializing location manager" );
   self.locationManager = [[CLLocationManager alloc] init];
   locationManager.delegate = self;
   [locationManager startUpdatingLocation];
   [self startMonitoringRegion];
   [self performSelector:@selector(printMonitoredRegions) withObject:nil afterDelay:2.];
   return YES;
}
- (void)locationManager:(CLLocationManager *)manager 
    didUpdateToLocation:(CLLocation *)newLocation 
           fromLocation:(CLLocation *)oldLocation
{
   //NSLog( @"location updated" );
}
-(void)     locationManager:(CLLocationManager*)manager 
didStartMonitoringForRegion:(CLRegion*)region
{
   NSLog( @"region monitoring started" );
}
-(void) locationManager:(CLLocationManager*)manager didEnterRegion:(CLRegion*)region
{
   NSLog( @"did enter region" );
}
-(void) locationManager:(CLLocationManager*)manager didExitRegion:(CLRegion*)region
{
   NSLog( @"did exit region" );
}
- (void)   locationManager:(CLLocationManager *)manager
monitoringDidFailForRegion:(CLRegion *)region 
                 withError:(NSError *)error
{
   NSLog( @"region monitoring failed" );
}
- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error
{
   NSLog( @"location manager failed" );
}
@end
Log:
2012-02-21 10:53:50.397 locationtest[64440:f803] initializing location manager
2012-02-21 10:53:50.412 locationtest[64440:f803] trying to start monitoring for region (identifier majorRegion) <LAT,LONG> radius 50.00m
2012-02-21 10:53:52.414 locationtest[64440:f803] printing regions:
2012-02-21 10:53:52.416 locationtest[64440:f803] (identifier majorRegion <LAT,LONG> radius 50.00m
Edit 2: I just noticed that the iOS implementation of the CLLocationManagerDelegate protocol differs slightly from the Mac implementation -- notably, Mac doesn't have didStartMonitoringRegion. Could there be any way I'm accidentally using the Mac libraries instead of the iOS libraries?