#iphone #objective-c #ios #xcode #cocoa-touch
#iPhone #objective-c #iOS #xcode #cocoa-touch
Вопрос:
Итак, член проектной группы и я работали над нашими частями отдельно. Я работал над половиной просмотров в приложении, а он работал над другой половиной. Я отправил ему свою половину для объединения с его половиной, но когда он попытался открыть мою половину и запустить ее, мы получили противоречивые результаты. Мы еще не объединили их, поэтому они не должны действовать по-разному. Я попытался протестировать его на нескольких других компьютерах, и все они дали одинаковый результат (отличный от моего).
Предполагается, что следующий код выводит «ПРОВЕРЕННЫЙ X». X представляет количество ячеек, отмеченных в этой точке. На моем компьютере выводится надпись «ПРОВЕРЕНО 1 ..2 ..3 .. 4», и вы можете выбрать только до 4, в зависимости от того, сколько помечено. На любом другом компьютере выводится «ПРОВЕРЕНО 0», и вы можете отметить столько, сколько захотите (но вы не можете снять их). Код для их пометки находится здесь:
- (void) tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView cellForRowAtIndexPath: indexPath];
[tableView deselectRowAtIndexPath:indexPath animated:YES];
if ((cell.accessoryType == UITableViewCellAccessoryNone) amp;amp; [[DataContainerSingleton theDataContainerSingleton].favourites count] < 4 amp;amp; ![self.tickedIndexPaths containsObject:indexPath])
{
cell.accessoryType = UITableViewCellAccessoryCheckmark;
[self.tickedIndexPaths addObject:indexPath];
[[DataContainerSingleton theDataContainerSingleton].favourites addObject:[drinks objectAtIndex:indexPath.row]]; // DOES NOT ADD AN OBJECT?
NSLog(@"CHECKED %d", [[DataContainerSingleton theDataContainerSingleton].favourites count]);
}
else if (cell.accessoryType == UITableViewCellAccessoryCheckmark)
{
[self.tickedIndexPaths removeObject:indexPath];
for (int i = 0; i < [[DataContainerSingleton theDataContainerSingleton].favourites count]; i )
{
NSString *drinkName = [[drinks objectAtIndex:indexPath.row] name];
NSString *favName = [[[DataContainerSingleton theDataContainerSingleton].favourites objectAtIndex:i] name];
if ([drinkName isEqualToString: favName])
{
cell.accessoryType = UITableViewCellAccessoryNone;
[[DataContainerSingleton theDataContainerSingleton].favourites removeObjectAtIndex:i];
NSLog(@"UNCHECKED %d", [[DataContainerSingleton theDataContainerSingleton].favourites count]);
}
}
}
}
Мне кажется, что массив избранных в моем контейнере данных singleton не заполняется. Массив drinks не пуст.
Вот код для класса DataContainerSingleton:
DataContainerSingleton.h
#import <Foundation/Foundation.h>
@interface DataContainerSingleton : NSObject
{
NSMutableArray *favourites;
NSMutableArray *drinks;
NSString *name;
int caffeine;
@private
}
@property (nonatomic, retain) NSMutableArray *favourites;
@property (nonatomic, retain) NSMutableArray *drinks;
@property (nonatomic, retain) NSString *name;
@property (nonatomic, assign) int caffeine;
(DataContainerSingleton *) theDataContainerSingleton;
@end
DataContainerSingleton.m
#import "DataContainerSingleton.h"
@implementation DataContainerSingleton
@synthesize favourites, drinks;
@synthesize name, caffeine;
static DataContainerSingleton* _theDataContainerSingleton = nil;
(DataContainerSingleton*) theDataContainerSingleton;
{
if (!_theDataContainerSingleton)
_theDataContainerSingleton = [[DataContainerSingleton alloc] init];
return _theDataContainerSingleton;
}
- (id)init
{
self = [super init];
if (self)
{
self.favourites = [[[NSMutableArray alloc] init] autorelease];
}
return self;
}
- (void)dealloc
{
[super dealloc];
}
@end
Я проверил все зависимости в программе, ни одна из них не находится за пределами папки, которую я копирую. Я очистил и очистил папку сборки, но она по-прежнему выводит 0.
У кого-нибудь есть идеи, что может быть причиной этого несоответствия? Заранее спасибо.
Ответ №1:
Я отправил ему свою половину для объединения с его половиной
Начните использовать программное обеспечение для контроля версий. Вы излишне усложняете себе задачу. Поначалу процесс обучения невелик, но он окупается даже в вашем первом нетривиальном проекте.
Если вы уверены, что у вас есть идентичные копии кодовой базы, вы, вероятно, можете сузить ее до одного из следующих:
-
Другой набор инструментов. Убедитесь, что вы оба используете одну и ту же версию Xcode с одинаковыми версиями всех SDK и т. Д.
-
Разные данные. Удалите приложение со своих устройств и повторите попытку.
-
Сохраняющиеся файлы в пакете. Установка версии для разработки через Xcode не удаляет старые файлы из пакета. В вашем пакете могут быть файлы, которых у него нет, или наоборот. Удалите приложение со своих устройств и повторите попытку.
-
Разное оборудование. Иногда ошибки проявляются только на определенном оборудовании. Разные возможности устройства могут отправлять один и тот же код по разным путям. Вы оба временно тестируете в симуляторе.
Комментарии:
1. Я проверил, что версия (и сборка) XCode одинаковы на обоих компьютерах, на которых я его тестировал. Кроме того, я удалил приложение, и оно по-прежнему делает то же самое. Я не переустанавливал XCode раньше, я устанавливал его только один раз. Мы просто тестируем его в симуляторе iPhone, мы еще не проводили тестирование на реальных iPhone.
Ответ №2:
Я думаю, что упомянутые вами «противоречивые результаты» могут быть связаны с тем фактом, что вы, возможно, установили соединение в Interface Builder для delegate
и dataSource
вашего tableView
с DataContainerSingleton
, но у вашего друга другая версия .xib
, в которой это соединение отсутствует. Это не дало бы никаких ошибок компиляции или предупреждений, но представило бы себя как «ошибка», когда ни один из методов делегата или источника данных фактически не вызывается. Поскольку вы можете видеть инструкции ведения журнала, я бы предположил delegate
, что значение установлено правильно, но dataSource
это не так ..?
Другой вариант заключается в том, что ваш cellForRowAtIndexPath
метод каждый раз возвращает новую ячейку (без флажка, поэтому вы можете только проверять, но никогда не снимать флажок).
РЕДАКТИРОВАТЬ: чтобы быть более точным в этом, у вас должен быть код в cellForRowAtIndexPath
следующих строках:
UITableViewCell *cell;
cell = [tableView dequeueReusableCellWithIdentifier:@"drinkCell"];
if(cell == nil) // we need to create a new one
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:@"drinkCell"];
}
if([tickedIndexPaths containsObject:indexPath])
{
cell.accessoryType = UITableViewCellAccessoryCheckmark;
} else {
cell.accessoryType = UITableViewCellAccessoryNone;
}
В противном случае, если на iPhone мало памяти, ОС попросит приложение удалить из памяти любые не совсем необходимые объекты, в том числе ваши существующие ячейки. Поэтому, например, в следующий раз, когда вы перейдете к извлечению ячейки в строке 2, ей придется создать новый UITableViewCell
объект со значениями по умолчанию, что означает принадлежность None
. В связи с этим вы должны явно устанавливать флажок каждый раз, когда получаете ячейку.
После просмотра вашего первого комментария: Хорошо. Вы должны убедиться, что не добавили дубликат indexPath
. Если выбрана строка, убедитесь, что checkedIndexPaths
она не содержит путь, который вы собираетесь добавить.
Комментарии:
1. Первый вариант невозможен, поскольку они буквально являются точными копиями друг друга. У меня есть второй компьютер, на котором я сейчас его тестирую, и он дает мне результаты, отличные от результатов ноутбука, который я использую прямо сейчас. Я скопировал его прямо туда и открыл точную копию того же файла. Я проверил делегат и источник данных моего TableView, и они оба установлены правильно. На самом деле вызывается метод didSelectRowAtIndexPath, я проверил с помощью контрольной точки. Я распечатывал tickedIndexPaths каждый раз, когда вызывал описанный выше метод, и на самом деле он превышает 4. Массив drinks инициализирован.