【问题标题】:The best practices to to create global variable创建全局变量的最佳实践
【发布时间】:2015-01-15 09:17:48
【问题描述】:

我正在开发 IOS 静态库。 我需要创建只能在这个库中访问的全局变量。 我知道 3 种方法来做到这一点

问题是,哪种方式更好。


第一个解决方案: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

米:

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

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

在代码中使用:

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

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

常量.h:

extern int *kCounter ;

在代码中使用:

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

谢谢

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

【问题讨论】:

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


    【解决方案1】:

    对于大多数类型,您可以使用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】:

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

      但是,如果您认为您只会使用 1 或 2 个变量作为全局变量,那么您的第三种方法是正确的。

      【讨论】:

      • 将代码放在一个类之外,使其难以重用?
      【解决方案3】:

      嗯,最好的解决方案是,没有全局。这总是可能的。你真的应该重新检查一下需求。

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

      请重新检查。

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

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

      我们开始吧:

      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;
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-12-19
        • 1970-01-01
        • 2018-04-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-04-16
        • 2016-07-23
        相关资源
        最近更新 更多