如何将局部变量更改为实例变量?

时间:2013-02-26 00:50:22

标签: ios objective-c cocoa

所以我对此完全陌生。 我正在关注当地的天气教程

http://www.icodeblog.com/2010/09/03/adding-local-weather-conditions-to-your-app-part-12-implementing-corelocation/

它不能正常工作。当我点击RUN时,会弹出一个窗口,说明您是否允许此应用访问位置管理器。但是在我有机会击中它之前消息消失了,然后应用程序什么也没做。

以下是我的代码......经过研究我发现了这个信息

虽然很难追查,但解决方法非常简单。

通过大量试验和错误,我发现当您第一次尝试访问应用程序中的任何位置服务时会弹出位置访问对话框,如果{{},对话框将自行消失(无需任何用户交互)在用户响应对话框之前释放{1}}对象。

我在CLLocationManager方法中创建了CLLocationManager个实例。由于这是该方法的本地实例,因此该方法在方法完成执行后由viewDidLoad释放。实例一释放,对话框就消失了。解决方案相当简单。将ARC实例从方法级变量更改为类级实例变量。现在CLLocationManager实例仅在卸载类时才会释放。

这可能是答案,但我不知道如何从方法级别更改为类级别varable。

有人可以协助将此更改为班级变量吗?

这是我的代码

CLLocationManager

2 个答案:

答案 0 :(得分:2)

您需要解决一些问题。首先,您的locationManager已经是一个实例变量。那里没有任何改变。但是您声明locationManager属性但从不使用它。摆脱财产或实际使用它。如果您保留该属性,则不需要公开,因为没有外部类正在使用它。

此外,您的delegate属性定义不正确。

您遇到的真正问题是您的应用委托代理实施。您创建LocationGetter的本地实例,然后在方法结束时将其超出范围。您需要向应用程序委托添加LocationGetter实例变量。这将允许实例保持活动的时间长于didFinishLaunchingWithOptions:方法。

以下是我将如何更新代码(假设启用了ARC):

LocationGetter.h:

#import <Foundation/Foundation.h>
#import <CoreLocation/CoreLocation.h>

@protocol LocationGetterDelegate <NSObject>
@required
- (void) newPhysicalLocation:(CLLocation *)location;
@end

@interface LocationGetter : NSObject

-(void)startUpdates;

@property (nonatomic, weak) id<LocationGetterDelegate> delegate;

@end

LocationGetter.m:

#import "LocationGetter.h"
#import <CoreLocation/CoreLocation.h>

@interface LocationGetter () <CLLocationManagerDelegate>

@property (nonatomic, strong) CLLocationManager *locationManager;

@end

@implementation LocationGetter {
    BOOL didUpdate = NO;
}

- (void) startUpdates{
    NSLog(@"Starting Location Updates");

    if (self.locationManager == nil)
        self.locationManager = [[CLLocationManager alloc]init];
    self.locationManager.delegate = self;

    self.locationManager.desiredAccuracy = kCLLocationAccuracyKilometer;
    [self.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 *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
{
    if (didUpdate)
        return;

    didUpdate = YES;
    // Disable future updates to save power.
    [manager stopUpdatingLocation];

    // let our delegate know we're done
    [self.delegate newPhysicalLocation:newLocation];
}

@end

AppDelegate.h:

#import <UIKit/UIKit.h>

@class ViewController;

@interface AppDelegate : UIResponder <UIApplicationDelegate>

@property (strong, nonatomic) UIWindow *window;
@property (strong, nonatomic) ViewController *viewController;
@property (nonatomic, strong) CLLocation *lastKnownLocation;

@end

AppDelegate.m:

#import "AppDelegate.h"
#import "ViewController.h"
#import "LocationGetter.h"

@interface AppDelegate () <LocationGetterDelegate>
@property (nonatomic, strong) LocationGetter *locationGetter;
@end

@implementation AppDelegate

- (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
    self.locationGetter = [[LocationGetter alloc] init];
    self.locationGetter.delegate = self;
    [self.locationGetter startUpdates];

    // Add the view controller's view to the window and display.
    [window addSubview:viewController.view];
    [window makeKeyAndVisible];

    return YES;
}

答案 1 :(得分:1)

我认为你的意思是将它改为实例变量而不是类变量(Objective-C没有这样的概念)。好吧,你已经做到了。住在这里的任何东西:

@interface Foo : SuperFoo
{
    //...
}

或者在这里:

@implementation Foo
{
    //...
}

是一个实例变量。