【问题标题】:Objective-C Defining a Global Array for use by several ViewControllersObjective-C 定义一个供多个 ViewControllers 使用的全局数组
【发布时间】:2016-06-05 05:50:21
【问题描述】:

我一直在尝试从我认为是我已经实现的单例类中实现一个全局 NSMutableArray。

我可以进入ViewController#2,向数组中添加和删除对象。

但是,当我离开 ViewController #2 并返回时,数据不会保留,并且我有一个包含 0 个对象的数组。

你认为我做错了什么?

.h

//  GlobalArray.h
@interface GlobalArray : NSObject{
    NSMutableArray* globalArray;
}

+(void)initialize;

.m

#import "GlobalArray.h"

@implementation GlobalArray

static GlobalArray* sharedGlobalArray;

NSMutableArray* globalArray;

+(void)initialize{
    static BOOL initalized = NO;
    if(!initalized){
        initalized = YES;
        sharedGlobalArray = [[GlobalArray alloc] init];
    }
}

- (id)init{
    if (self = [super init]) {
        if (!globalArray) {
            globalArray = [[NSMutableArray alloc] init];
        }
    }
    return self;
}

查看控制器 #2

GlobalArray* myGlobalArray;
myGlobalArray = [[GlobalArray alloc] init];

//Various add and remove code

感谢您的意见。

【问题讨论】:

  • 您不是在创建单例实例并访问共享实例;您只是每次都创建一个新实例。见galloway.me.uk/tutorials/singleton-classes
  • 有很多关于如何在 Objective-C 中正确创建单例的答案。

标签: ios objective-c arrays xcode


【解决方案1】:

以下是在应用程序级别全球共享数据的最佳方法。单例类是关键。单例只初始化一次,其余时间返回共享数据。

@interface Singleton : NSObject
@property (nonatomic, retain) NSMutableArray * globalArray;
  +(Singleton*)singleton;
@end

@implementation Singleton
@synthesize globalArray;
+(Singleton *)singleton {
    static dispatch_once_t pred;
    static Singleton *shared = nil;
    dispatch_once(&pred, ^{
        shared = [[Singleton alloc] init];
        shared.globalArray = [[NSMutableArray alloc]init];
    });
    return shared;
}
@end

以下是访问/使用共享数据的方式。

NSMutableArray * sharedData = [Singleton singleton].globalArray;

【讨论】:

    【解决方案2】:

    您使用以下代码在 ViewController#2 中创建单独的 GlobalArray 实例:

    GlobalArray* myGlobalArray;
    myGlobalArray = [[GlobalArray alloc] init];
    

    相反,您应该创建访问器方法来返回您的共享实例,如下所示:

    //  GlobalArray.h
    @interface GlobalArray : NSObject{
        NSMutableArray* globalArray;
    }
    
    +(void)initialize;
    +(GlobalArray*)sharedInstance;
    

    实施:

    // GlobalArray.m
    
    // ... your existing code
    
    // accessor method
    +(GlobalArray*)sharedInstance
    {
        return sharedGlobalArray;
    }
    

    然后从您的 ViewController#2 中调用它:

    GlobalArray* myGlobalArray = [GlobalArray sharedInstance];
    

    但是,使用全局变量在视图控制器之间传输数据是不好的做法;我建议你使用更安全的方法,例如创建一个委托。

    【讨论】:

      【解决方案3】:

      要创建一个共享的全局数组,如果这确实是你想要的,只需将它放在头文件中:

      extern NSMutableArray *myGlobalArray;
      

      这在你的主源文件中:

      NSMutableArray *myGlobalArray;
      
      - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
         myGlobalArray = [NSMutableArray new];
      }
      

      【讨论】:

      • AppDelegate 不是存放随机位全局数据的地方。
      • 当然,如果您愿意,可以将其放入自己的文件中,但这是向某人解释全局变量如何工作的最简单方法,而无需进入单例、dispatch_once 和/或 +initialize。无论哪种方式,viewControllers 都将依赖于其他代码片段,因此任何对应用程序委托中的全局变量的道德愤慨在小型应用程序中都是无关紧要的。
      【解决方案4】:

      使用此代码设置和获取数组视图,添加和删除在控制器本身中分开。

      //  GlobalArray.h
      @interface GlobalArray : NSObject
      @property (nonatomic, strong) NSMutableArray* globalArray;
      + (id)sharedManager;
      -(NSMutableArray *) getGlobalArray;
      -(void) setGlobalArray:(NSMutableArray *)array;
      @end
       /*-----------------------------------------*/
      #import "GlobalArray.h"
      
      @implementation GlobalArray
          
      + (id)sharedManager {
          static GlobalArray *sharedMyManager = nil;
          static dispatch_once_t onceToken;
          dispatch_once(&onceToken, ^{
              sharedMyManager = [[self alloc] init];
          });
          return sharedMyManager;
      }
      
      - (id)init{
          if (self = [super init]) {
              if (!globalArray) {
                  globalArray = [[NSMutableArray alloc] init];
              }
          }
          return self;
      }
      
      -(NSMutableArray *) getGlobalArray{
         return self.globalArray;
      }
      -(void) setGlobalArray:(NSMutableArray *)array{
         _globalArray = globalArray;
      }
      @end
      
      -------------------------
      //get array
      NSArray * array = [[GlobalArray sharedManager] getGlobalArray];
      
      //set array
      [[GlobalArray sharedManager] setGlobalArray:array]
      -------------------------
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-06-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-10-26
        • 1970-01-01
        相关资源
        最近更新 更多