创建全局变量的最佳实践

时间:2015-01-15 09:17:49

标签: ios objective-c iphone xcode global-variables

我正在研究IOS静态库。 我需要创建仅在此库中可访问的全局变量。 我知道有三种方法可以做到这一点

问题是,哪种方式更好。


第一个解决方案: SharedInstance

·H:

  @interface GlobalVars : NSObject
    @property  int counter;
    +(instancetype)sharedInstance;
@end

的.m:

 @implementation GlobalVars
    +(instancetype)sharedInstance {

        static dispatch_once_t p = 0;
        __strong static id _sharedObject = nil;
        dispatch_once(&p, ^{
            _sharedObject = [[self alloc] init];
        });
        return _sharedObject;
    }

    +(int)counter{
    return [GlobalVars sharedInstance].counter;
    }

    +(void)setCounter:(int)_counter{
    [GlobalVars sharedInstance].counter=_counter;
    }
@end

在代码中使用:

  [GlobalVars setCounter:5];
    int i= GlobalVars.counter

第二个解决方案:静态变量+类方法

h:

 @interface GlobalVars
 + (int) counter;
 + (void) setCounter:(int)val;
 @end

m:

 @implementation GlobalVars
 static int value;
+ (int) counter {   
 return value;
   }

+ (void) setCounter:(int)val {
 value = val; 
 }
     @end

在代码中使用:

   [GlobalVars setCounter:5];
    int i= GlobalVars.counter

第三种解决方案:外部变量

Constants.h:

extern int *kCounter ;

在代码中使用:

#import "Constants.h"
-(void)someMethod{
kCounter=5;
int i=kCounter;
}

由于

编辑: 解决方案必须是“线程安全”

3 个答案:

答案 0 :(得分:0)

你应该使用Singelton设计模式来创建全局变量,因为你可以在单个实例中使用out class,将来,如果你想要一些更多的全局变量,那么你可以使用相同的Singelton类。所以我认为你的第一种方法是更好。

但是,如果您认为只使用1或2变量作为全局变量,则第3种方法是正确的。

答案 1 :(得分:0)

对于大多数类型,您可以使用NSUserDefaults。在AppDelegate中,您可以注册默认值,然后在任何范围内修改它们。

Example

保存

NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];

// saving an NSString
[prefs setObject:@"TextToSave" forKey:@"keyToLookupString"];

// saving an NSInteger
[prefs setInteger:42 forKey:@"integerKey"];

// saving a Double
[prefs setDouble:3.1415 forKey:@"doubleKey"];

// saving a Float
[prefs setFloat:1.2345678 forKey:@"floatKey"];

// This is suggested to synch prefs, but is not needed (I didn't put it in my tut)
[prefs synchronize];

检索

NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];

// getting an NSString
NSString *myString = [prefs stringForKey:@"keyToLookupString"];

// getting an NSInteger
NSInteger myInt = [prefs integerForKey:@"integerKey"];

// getting an Float
float myFloat = [prefs floatForKey:@"floatKey"];

答案 2 :(得分:0)

嗯,最好的解决方案是,没有全球性的。这总是可能的。你应该重新检查这个需求。

您已完成此操作,但仍需要全局变种。

请重新检查。

您已完成此操作,但仍需要全局变种。

如果你必须安全地使用该线程,那么很明显你需要一段代码来使线程安全。因此,最后一个变体 - 直接访问全局变量 - 无法工作。但您仍然可以使用全局变量,但必须添加函数才能访问它。你可以在简单的C中轻松地做到这一点(惊喜?每天都没有C开发人员遇到同样的问题吗?)我更喜欢这个,因为全局变量不是对象状态。那么使用对象的方式呢? (类是没有模块。它们是对象的构造计划。)

我们走了:

something.h

void setCounter( int counter );
int getCounter( void );

something.c(或.m)

static int counter; // The asterik * is a typo?

void setCounter( int newCounter )
{
   // Do something for being thread safe, i. e. locking or GCD
   counter = newCounter;
}

int getCounter( void )
{
   // Do something for being thread safe, i. e. locking or GCD
   return counter;
}