2014-11-06 7 views
1

Я пытаюсь добавить некоторые данные из случайного класса к моему ViewController,Singleton UIViewController

Так держать всегда одни и те же данные, что я сделал синглтон на моем UIViewController, но он не работает, я никогда не получить данные на моем столе.

это то, что я добавил к моему UIViewController:

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

и из моего класса я называю это, делая это:

MBViewController *vc = [MBViewController sharedMBVC]; 

Должен ли я установить где-то содержание моих NSArrays, что они объявлены в моей viewDidLoad диспетчера представлений? или есть что-то еще.

PS: я делал в моем классе, прежде чем vc = (MBViewController *)[[[[UIApplication sharedApplication] delegate] window] rootViewController]; но теперь мой UIViewController его не rootview больше, вот почему им пытаются найти другой способ доступа к нему, и я думаю, что лучшим решением будет сделать синглтона

Может ли помочь мне ребята

+1

Не делайте этого. Это плохо. Что вы делаете, что заставляли вас использовать синглтон? Там ** - это лучший способ сделать это. – Fogmeister

+0

@Fogmeister the main pb - это то, что теперь я использую AMSlideMenu, что его MainVC становится rootview, поэтому теперь у меня нет доступа к моим методам MBViewController: si хочет всегда иметь текущий MBViewController с обновленными NSArrays – fourthnovember

+0

Зачем вам нужно доступ к MBViewController повсюду? Это просто, чтобы получить массивы? – Fogmeister

ответ

3

ОК, поэтому проблема заключается в том, что viewController, который отображает массивы, также «владеет» массивами. Это означает, что (с вашей текущей настройкой), чтобы иметь возможность изменять массивы, вам нужно получить контроль над viewController, чтобы иметь доступ к массивам.

Вам необходимо изменить это, удалив массивы с этого viewController.

Вы все еще можете сделать это с помощью сингла (если хотите), но создайте совершенно новый класс под названием что-то вроде ArrayManager.

Это будет содержать массивы и ВСЕ методы обновления массивов.

Так, например, если ваш viewController имеет метод под названием - (void)addObjectToArray:(id)object;, то переместите этот метод на одноэлементный класс ArrayManager.

Теперь в вашем отображении ViewController вы можете сделать ...

[[ArrayManager sharedInstance] getSomeDataFromTheArray]; 

И в том месте, которое должно обновить массив, который вы можете сделать ...

[[ArrayManager sharedInstance] addObjectToArray:someObject]; 

Теперь вы не нужно беспокоиться о том, чтобы пропустить viewController вообще.

Это может быть улучшено с помощью различных вещей. Например, вы, возможно, не нужен синглтон на все и можете просто взять этот ArrayManager класс и впрыснуть его в те места, которые нуждаются в ней путем установки свойства и т.д. ...

Кроме того, вы могли бы использовать CoreData для хранения информации.

Кроме того, ваш метод singleton неверен. Способ, рекомендованный 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; 
} 
+0

большое спасибо – fourthnovember

+0

Я сделал это, я получил то же самое, что данные не отображаются, в viewDidLoad я называю мой singleton класс MyClass * myclass = [MyClass sharedInstance]; затем _array1 = myclass.array1; – fourthnovember

+0

, когда я вызываю adddata в viewcontroller, метод вызывает adddata Myclass, я помещаю точку останова, все хорошо туда, но после того, как я вернусь к моему диспетчеру просмотра, я делаю array1 = myclass.array1; снова, а затем [self.tableview reloadData]; но он никогда не перезагружает, я имею в виду, что он не вызывает какой-либо метод tableview: s, у вас есть идея, почему я это делаю? – fourthnovember

-1

Вместо инициализации ваших массивов в viewDidLoad сделайте это в функции sharedMBVC. Это гарантирует, что массивы не будут повторно инициализированы каждый раз при загрузке представления.

+0

Это разумно, но он никак не отвечает на вопрос OP. Вместо этого это должен быть комментарий. – FreeNickname

+0

это не работает: s – fourthnovember

2

Ну, я думаю, эти массивы не принадлежат к MBViewController с архитектурной точки зрения. Я бы разделил их на уровень данных (например, класс DataSource, например) и сохранил ссылку на DataSource везде, где вам нужно. Посмотрите на Second iOS App tutorial от Apple. Он содержит простой пример реализации уровня данных. ОБНОВЛЕНИЕ: Кроме того, ознакомьтесь с ответом Fogmeister. Он объясняет возможную реализацию такого объекта довольно хорошо :)

Что касается того, почему однотонный не работал, как вы ожидали, в этом случае, я полагаю, причина может быть следующей: Если вы доберетесь до MBViewController через segue (который, я думаю, вы есть), то каждый раз создается новый экземпляр MBViewController. Если вы получаете доступ к своим массивам из MBViewController, используя self.myArray, то вы получаете доступ к этому новому MBViewControllermyArray. В то время как sharedMBVC хранит ссылку на общий экземпляр, он просто игнорируется segue.

+0

большое спасибо – fourthnovember

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

    } 

} 
Смежные вопросы