だから私はこれに完全に慣れていません。私は地元の天気のチュートリアルに従っています
正常に機能していません。RUN を押すと、このアプリにロケーション マネージャーへのアクセスを許可するかどうかを示すウィンドウがポップアップ表示されます。しかし、メッセージを打つ前にメッセージが消えてしまい、アプリは何もしません。
以下は私のコードです...調査すると、この情報が見つかりました
追跡するのは困難ですが、これに対する解決策は非常に簡単です。
多くの試行錯誤の結果、アプリ内の位置情報サービスに初めてアクセスしようとすると、位置情報アクセス ダイアログがポップアップしますが、CLLocationManager
オブジェクトが以前に解放されると、ダイアログは (ユーザーの操作なしで) 自動的に消えることがわかりました。ユーザーがダイアログに応答します。
CLLocationManager
メソッドでインスタンスを作成していましたviewDidLoad
。これはメソッドのローカル インスタンスであるため、メソッドのARC
実行が完了した後にインスタンスが解放されました。インスタンスが解放されるとすぐに、ダイアログが消えました。解決策はかなり単純でした。CLLocationManager
インスタンスをメソッド レベルの変数からクラス レベルのインスタンス変数に変更します。CLLocationManager
クラスがアンロードされると、インスタンスが解放されるようになりました。
これが答えかもしれませんが、メソッドレベルからクラスレベルの変数に変更する方法がわかりません。
これをクラスレベルの変数に変更するのを手伝ってもらえますか?
ここに私のコードがあります
#import <Foundation/Foundation.h>
#import <CoreLocation/CoreLocation.h>
@protocol LocationGetterDelegate <NSObject>
@required
- (void) newPhysicalLocation:(CLLocation *)location;
@end
@interface LocationGetter : NSObject
<CLLocationManagerDelegate>{
CLLocationManager *locationManager;
id delegate;
}
-(void)startUpdates;
@property (nonatomic, retain) CLLocationManager *locationManager;
@property (nonatomic, retain) id delegate;
@end
#import "LocationGetter.h"
#import <CoreLocation/CoreLocation.h>
@implementation LocationGetter
@synthesize locationManager,delegate;
BOOL didUpdate = NO;
- (void) startUpdates{
NSLog(@"Starting Location Updates");
if (locationManager == nil)
locationManager = [[CLLocationManager alloc]init];
locationManager.delegate = self;
locationManager.desiredAccuracy = kCLLocationAccuracyKilometer;
[locationManager startUpdatingLocation];
}
- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error
{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Error" message:@"Your location could not be determined." delegate:nil cancelButtonTitle:@"OK" otherButtonTitles: nil];
[alert show];
}
// Delegate method from the CLLocationManagerDelegate protocol.
- (void)locationManager:(CLLocationManager *)manage didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
{
if (didUpdate)
return;
didUpdate = YES;
// Disable future updates to save power.
[locationManager stopUpdatingLocation];
// let our delegate know we're done
[delegate newPhysicalLocation:newLocation];
}
@end
#import <UIKit/UIKit.h>
#import "LocationGetter.h"
@class ViewController;
@interface AppDelegate : UIResponder
<UIApplicationDelegate, LocationGetterDelegate>
{
UIWindow *window;
ViewController *viewController;
CLLocation *lastKnownLocation;
}
@property (retain, nonatomic) UIWindow *window;
@property (retain, nonatomic) ViewController *viewController;
@property (nonatomic, retain) CLLocation *lastKnownLocation;
@end
#import "AppDelegate.h"
#import "ViewController.h"
#import "LocationGetter.h"
@implementation AppDelegate
@synthesize lastKnownLocation;
@synthesize viewController;
@synthesize window;
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
// // Override point for customization after application launch.
// self.viewController = [[ViewController alloc] initWithNibName:@"ViewController" bundle:nil];
// self.window.rootViewController = self.viewController;
// [self.window makeKeyAndVisible];
UIActivityIndicatorView *spinner = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge];
spinner.center = CGPointMake(self.viewController.view.frame.size.width / 2, self.viewController.view.frame.size.height / 2);
[spinner startAnimating];
[viewController.view addSubview:spinner];
// get our physical location
LocationGetter *locationGetter = [[LocationGetter alloc] init];
locationGetter.delegate = self;
[locationGetter startUpdates];
// Add the view controller's view to the window and display.
[window addSubview:viewController.view];
[window makeKeyAndVisible];
return YES;
}
- (void)applicationWillResignActive:(UIApplication *)application
{
// Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
// Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
}
- (void)applicationDidEnterBackground:(UIApplication *)application
{
// Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
// If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
}
- (void)applicationWillEnterForeground:(UIApplication *)application
{
// Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
}
- (void)applicationDidBecomeActive:(UIApplication *)application
{
// Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
}
- (void)applicationWillTerminate:(UIApplication *)application
{
// Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
}
- (void)newPhysicalLocation:(CLLocation *)location {
// Store for later use
self.lastKnownLocation = location;
// Remove spinner from view
for (UIView *v in [self.viewController.view subviews])
{
if ([v class] == [UIActivityIndicatorView class])
{
[v removeFromSuperview];
break;
}
}
// Alert user
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Location Found" message:[NSString stringWithFormat:@"Found physical location. %f %f", self.lastKnownLocation.coordinate.latitude, self.lastKnownLocation.coordinate.longitude] delegate:nil cancelButtonTitle:@"OK" otherButtonTitles: nil];
[alert show];
}
@end