Singleton UIViewController

时间:2014-11-06 10:29:27

标签: ios objective-c iphone uitableview uiviewcontroller

我试图将随机类中的一些数据添加到我的viewController,

所以为了保持相同的数据,我在我的UIViewController上做了一个单例,但它不起作用我从来没有得到我的tableview上的数据。

这是我添加到我的UIViewController:

+(id)sharedMBVC {
   static MBViewController *sharedMBVC ;
    @synchronized(self) {
        if (!sharedMBVC)
            sharedMBVC = [[MBViewController alloc] init];
        return sharedMBVC;
    }
}

从我的课堂上我这样称呼它:

  MBViewController *vc = [MBViewController sharedMBVC];

我是否必须在我的NSArrays的内容中设置它们在viewcontroller的viewDidLoad中声明的内容?或者还有别的事可做。

PS:我在vc = (MBViewController *)[[[[UIApplication sharedApplication] delegate] window] rootViewController];之前在我的班级做,但现在我的uiviewcontroller不再是rootview,这就是为什么我试图找到其他方式来访问它,我想最好的解决方案是做一个单身人士

你能帮帮我吗

4 个答案:

答案 0 :(得分:3)

好的,所以你遇到的问题是显示数组的viewController也是"拥有"数组。这意味着(使用您当前的设置)能够更改您需要保持viewController才能访问数组的数组。

您需要通过从该viewController中删除数组来更改它。

你仍然可以使用单身人士(如果你愿意)这样做,但是创建一个名为ArrayManager的全新类。

这将包含数组和所有更新数组的方法。

例如,如果您的viewController有一个名为- (void)addObjectToArray:(id)object;的方法,那么将此方法移动到ArrayManager单例类。

现在在你的显示viewController中你可以做...

[[ArrayManager sharedInstance] getSomeDataFromTheArray];

在必须更新阵列的地方你可以做......

[[ArrayManager sharedInstance] addObjectToArray:someObject];

现在你根本不需要担心传递viewController。

这可以通过各种方式得到改善。例如,您可能根本不需要单身人士,可以通过设置属性等将此ArrayManager课程和注入放入需要它的地方......

此外,您可以使用CoreData存储信息。

此外,您的单例方法不正确。 Apple推荐的方式是使用......

+ (ArrayManager *)sharedInstance
{
    static dispatch_once_t once;
    static ArrayManager *arrayManager;
    dispatch_once(&once, ^{
        arrayManager = [[ArrayManager alloc] init];
    });
    return arrayManager;
}

重写您的单身人士......

.h文件

@interface PTVData : NSObject

+ (PTVData *)sharedInstance;

- (void)addSensor:(NSString *)sensorName;
- (NSInteger)numberOfSensors;
- (NSString *)sensorAtIndex:(NSUInteger)index;

@end

.m文件

@interface PTVData ()

@property (nonatomic, strong) NSMutableArray *sensors;

@end

@implementation PTVData

+ (PTVData)sharedInstance
{
    static PTVData *sharedPTVData;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        sharedPTVData  = [[PTVData alloc] init];
    });
    return sharedPTVData;
}

- (id)init
{
    if (self = [super init]) {
        _sensors = [[NSMutableArray alloc] initWithObject:@"None"];
    }
    return self;
}

- (void)addSensor:(NSString *)sensorName
{
    if (sensorName
        && ![self.sensors containsObject:sensorName]) {
        [self.sensors addObject:sensorName];
    }
}

- (NSInteger)numberOfSensors
{
    return self.sensors.count;
}

- (NSString *)sensorAtIndex:(NSUInteger)index
{
    return self.sensors[index];
}

@end

通过这样做,您可以隐藏实际的传感器阵列。它只能通过PTVData类直接访问。

现在在你的tableview方法中你可以做...

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return [[PTVData sharedInstance] numberOfSensors];
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    UITableViewCell *cell = ...

    cell.textLabel.text = [[PTVData sharedInstance] sensorAtIndex:indexPath.row];

    return cell;
}

答案 1 :(得分:2)

嗯,我认为,从架构的角度来看,这些数组并不属于MBViewController。我会将它们分离到数据层(例如某种类型的DataSource类),并在所需的任何地方保持对DataSource的引用。请查看Apple的Second iOS App tutorial。它包含一个简单的数据层实现示例。 的更新: 另外,看看Fogmeister的答案。他很好地解释了这种对象的可能实现:)

至于为什么单身人士在这种情况下没有像你期望的那样工作,我相信,原因可能如下: 如果你通过segue(我认为你是)来到MBViewController,那么每次都会创建一个MBViewController的新实例。如果使用self.myArray从MBViewController访问数组,则可以访问这个新的MBViewController' s myArray。虽然sharedMBVC保留了对共享实例的引用,但它只是被segue忽略了。

答案 2 :(得分:0)

在我的ViewController.h中

@property PTVData *ptvdata; 

ViewController.m viewDidLoad中

   ptvdata = [PTVData sharedPTVData];
    _sensorsCollection = ptvdata.sensorsCollection; 

然后我的ViewController.m中有一个方法

- (void) addSensorToCollection:( NSString *)sensorName{

  [[PTVData sharedPTVData] addSensorToCollection:sensorName];
    _sensorsCollection = ptvdata.sensorsCollection;

       [ self.tableView reloadData];


    }
}

我的PTVData.h

@property (nonatomic,retain) NSMutableArray *sensorsCollection;
+(id)sharedPTVData;
-(id) init;
- (void) addSensorToCollection:( NSString *)sensorName;
@end

我的PTVData.m

@synthesize sensorsCollection = _sensorsCollection;

+ (id)sharedPTVData {
    static PTVData *sharedPTVData  = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        sharedPTVData  = [[self alloc] init];
    });
    return sharedPTVData;
}

- (id)init {
    if (self = [super init]) {
           _sensorsCollection   = [[NSMutableArray alloc]initWithObjects:@"None", nil];
    }
    return self;
}
- (void) addSensorToCollection:( NSString *)sensorName{

    if (![_sensorsCollection containsObject:sensorName]&& sensorName!= nil) {
        [_sensorsCollection addObject:sensorName];

    }

}

答案 3 :(得分:-1)

不是在viewDidLoad中初始化数组,而是在sharedMBVC函数中执行。这将确保每次加载视图时都不会重新初始化数组。