Почему отдельный экземпляр класса ViewController влияет на предыдущий экземпляр? - PullRequest
0 голосов
/ 15 января 2012

ОБНОВЛЕНИЕ - Причина найдена! ... пожалуйста, прочитайте ниже и предложите решение:

При создании видео, чтобы показать эту проблему, я обнаружил, почему это происходит ...

Любой элемент управления / элемент, который определен между #imports & @implementation DetailViewController в .m файле, теряется исходным detVC при создании нового экземпляра VC.

Пример: Я включаю видео, которое воссоздает эту проблему. Как показано, все элементы управления работают, кроме UISegmentedControl & a UILabel .., оба из которых определены в DetailViewController.m как:

#import "DetailViewController.h"

UISegmentedControl *sortcontrol;
UILabel *incrementLabel;

@implementation DetailViewController

Ссылка на видео - http://www.youtube.com/watch?v=2ABdK0LkGiA

Я думаю, что мы довольно близки .. Жду ответа !!

P.S .: Я думаю, что этой информации достаточно, это может привести нас к решению, но при необходимости я тоже могу поделиться кодом.


РАНЕЕ:

В нашем приложении есть detailViewController (detVC), который обычно «выталкивается» из UITableViewController.

Теперь мы также реализуем Push-уведомления, которые будут «модально» представлять тот же detVC при получении уведомления, что, в свою очередь, может происходить на любом контроллере представления.

Все работает нормально, пока не будет представлено уведомление через detVC, в то время как другой экземпляр detVC уже был активным контроллером представления (выдвинутым ранее через TableView).

Проблема возникает, когда представленный detVC отклоняется - выдвинутый detVC «теряет» контроль над всем - Он не указывает на те же данные, что и раньше, и даже UISegmentedControl на панели навигации указывает на -1 index on нажимаем любой указатель!

Почему такое происходит, когда мы создаем отдельный экземпляр detVC? Почему это влияет на более раннюю версию detVC? Как это может быть решено / Что нужно узнать об цели C здесь? (К вашему сведению, мы используем ARC в проекте)

Спасибо


РЕДАКТИРОВАТЬ - Некоторые код:

При нажатии:

ProductDetailViewController *detailViewController = [[ProductDetailViewController alloc] init];    
detailViewController.hidesBottomBarWhenPushed = YES;  
[self.navigationController pushViewController:detailViewController animated:YES];
detailViewController.serverOffset=serverOffset;
detailViewController.prdctIndex = indexPath.row;

При представлении посредством уведомления:

- (void)displaySingleProduct:(NSDictionary*)userInfo{
    ProductDetailViewController *onePrdVC = [[ProductDetailViewController alloc] init];    
    UINavigationController *addNav = [[UINavigationController alloc] initWithRootViewController:onePrdVC];
    onePrdVC.justOne=YES;
    onePrdVC.onePrdIDtoLoad=[[[userInfo valueForKey:@"prd"] valueForKey:@"id"] intValue];
    [self.navigationController presentModalViewController:addNav animated:YES];
}

В detVC есть класс Product, который получает данные из значений, хранящихся в строке prdctIndex в таблице SQLite.

После отклонения представленного detVC посредством уведомления класс Product отправленного detVC начинает указывать на строку, которая использовалась для класса Product в представленном detVC. И в viewDidAppear нет такого кода, который изменил бы Product класс.

Итак, эта проблема UISegmentedControl, упомянутая выше, и некоторые другие проблемы вызывают боль! По сути, весь detVC ведет себя странно - и это снова работает, если мы просто вставим и снова нажмем его!


РЕДАКТИРОВАТЬ 2

У меня есть дополнительная информация, которая может привести к причине. Если я запускаю viewDidLoad на viewDidAppear, как это:

if (!justOne) {
    aProduct = [allProducts getProduct:(prdctIndex+1) one:NO];
    [self viewDidLoad];
    [self populateDetails];
}

нажатый detVC восстанавливает элемент управления, и каждый элемент / элемент управления начинает работать должным образом (но не в идеальном режиме). Таким образом, совершенно ясно, что отдельный экземпляр представленного detVC портит ранее выдвинутый detVC, и требуется переустановка всех элементов управления / указателей через viewDidLoad.

Можно ли из этой информации сделать полезный вывод?

Ответы [ 4 ]

1 голос
/ 18 января 2012

Когда в своем коде вы пишете:

#import "DetailViewController.h"

UISegmentedControl *sortcontrol;
UILabel *incrementLabel;

@implementation DetailViewController

Вы не определяете эти переменные как переменные экземпляра (ivars), поэтому они не являются индивидуальными для каждого экземпляра. Есть три способа определения иваров. 1) Традиционным способом, в вашем .h файле.

@interface DetailViewController{
    UISegmentedControl *sortcontrol;
    UILabel *incrementLabel; 
}

2) Некоторые дополнения к target-C добавили поддержку следующих двух способов. Например, объявив их в файле .m.

@implementation DetailViewController{
    UISegmentedControl *sortcontrol;
    UILabel *incrementLabel;
}

3) Если эти ивары используют свойства для их раскрытия, вы можете просто пропустить их явное определение. Так в .h:

@interface DetailViewController
@property (strong, nonatomic) IBOutlet UISegmentedControl *sortcontrol;
@property (strong, nonatomic) IBOutlet UILabel *incrementLabel;

и затем в файле .m:

@implementation DetailViewController
@synthesize sortcontrol;
@synthesize incrementLabel;
0 голосов
/ 16 января 2012

Если два экземпляра одного и того же класса мешают друг другу, это настоятельно рекомендует не сохранять все ваше состояние в переменных экземпляра.Я подозреваю, что что-то в ProductDetailViewController хранит свое состояние в глобальных данных или данных класса, и что ваша проблема там живет.

Возможно, вы сделали что-то глупое, например, сделав ProductDetailViewController принудительным синглтоном (переопределяя+alloc, что вы почти никогда не должны делать), но обычно люди помнят, когда они это сделали.


Никогда не звоните viewDidLoad напрямую.Это только для вызова системы.(Я знаю, что вы только что тестировали, но не оставляйте это.)

Но вы звоните [super viewDidAppear:animated] в свой viewDidAppear:?Вы должны вызвать ваш суперкласс в этом методе.

0 голосов
/ 16 января 2012

Это на самом деле зависит от того, как была создана архитектура вашего приложения.Если вы используете приложение на основе TabBarController, здесь является правильным способом сделать это.

0 голосов
/ 15 января 2012

Вы загружаете контроллер вида из NIB? Если так, возможно, каждый раз используется один и тот же экземпляр контроллера представления. Вы можете зарегистрировать адрес вашего контроллера представления в viewDidLoad и посмотреть, так ли это.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...