Сбой tableView при возврате из подробного просмотра iphone - PullRequest
1 голос
/ 14 июня 2011

в моем приложении у меня есть представление таблицы и подробное представление.Представление таблицы заполняется из запроса к базе данных.У меня есть методы этой базы данных в методе viewDidLoad (я не знаю, куда еще его поместить). Затем у меня есть метод [self.tableView reload] в методе viewWillAppear.Проблема в том, что, когда я возвращаюсь из подробного представления в табличное представление и щелкаю по тому же элементу (в табличном представлении), происходит сбой приложения.Я предполагаю, что это потому, что методы базы данных все еще работают, когда я возвращаюсь из подробного представления и нажимаю на ячейку.Таким образом, данные в табличном представлении никогда не перезагружаются.Ребята, у вас есть идеи, как это исправить?

* РЕДАКТИРОВАТЬ: * Вот код из базы данных, я использую его для заполнения табличного представления: *

- (void)viewDidLoad
{

    //Convert the course id to string 
    NSString *selectedCategoryIdConverted = [NSString stringWithFormat:@"%d", self.selectedCategory._id];

    NSMutableArray *tempArray = [[NSMutableArray alloc]init];

    // Set up sqlite statement
    sqlite3_stmt *dbStatement = nil;

    NSString *sqlQuery = [NSString stringWithFormat:@"SELECT co.name, co.id, o.location FROM course as co JOIN categories as ca JOIN occasions as o WHERE co.catID = ca.id AND co.catID = %i AND o.courseID = co.id", self.selectedCategory._id];

    //Convert the query string to const char
    const char *sqlQueryConverted =[sqlQuery UTF8String];

    int prepareSqlQuery = sqlite3_prepare_v2( [[DatabaseController sharedDatabaseController] getDb], sqlQueryConverted, -1, &dbStatement, NULL);

    //Run the query
    while ( sqlite3_step(dbStatement) == SQLITE_ROW ) 
    {    

            const char *name = (const char *)sqlite3_column_text(dbStatement, 0);
            int courseId = sqlite3_column_int(dbStatement, 1);
            const char *location = (const char *)sqlite3_column_text(dbStatement, 2);

            //Convert the returnedElement char to string
            NSString *nameConverted = [[[NSString alloc] initWithUTF8String:name] autorelease];
            NSString *locationConverted = [[[NSString alloc] initWithUTF8String:location] autorelease];

            Course *course = [[Course alloc] initWithName:nameConverted _id:courseId location:locationConverted];


            [tempArray addObject:course];

    }    

    self.courses = tempArray;

    [super viewDidLoad];
   }

РЕДАКТИРОВАТЬ: Я заметил, что когда я вернусь к представлению таблицы, приложение не будет сбой, если я нажимаю на следующий элемент, но если я нажимаю напредыдущий элемент (строка) в табличном представлении вылетает из приложения.

РЕДАКТИРОВАТЬ: Я изменил код на метод viewDidAppear и исправил утечку памяти.self.courses это (nonatomic, retain) вот код:

- (void)viewWillAppear:(BOOL)animated
{
    //Convert the course id to string 
    //NSString *selectedCategoryIdConverted = [NSString stringWithFormat:@"%d", self.selectedCategory._id];

    NSMutableArray *tempArray = [[NSMutableArray alloc]init];

    // Set up sqlite statement
    sqlite3_stmt *dbStatement = nil;

    NSString *sqlQuery = [NSString stringWithFormat:@"SELECT co.name, co.id, o.location FROM course as co JOIN categories as ca JOIN occasions as o WHERE co.catID = ca.id AND co.catID = %i AND o.courseID = co.id", self.selectedCategory._id];

    //Convert the query string to const char
    const char *sqlQueryConverted =[sqlQuery UTF8String];

    int prepareSqlQuery = sqlite3_prepare_v2( [[DatabaseController sharedDatabaseController] getDb], sqlQueryConverted, -1, &dbStatement, NULL);

    //Run the query
    while ( sqlite3_step(dbStatement) == SQLITE_ROW ) 
    {    

        const char *name = (const char *)sqlite3_column_text(dbStatement, 0);
        int courseId = sqlite3_column_int(dbStatement, 1);
        const char *location = (const char *)sqlite3_column_text(dbStatement, 2);

        //Convert the returnedElement char to string
        NSString *nameConverted = [[[NSString alloc] initWithUTF8String:name] autorelease];
        NSString *locationConverted = [[[NSString alloc] initWithUTF8String:location] autorelease];

        Course *course = [[Course alloc] initWithName:nameConverted _id:courseId location:locationConverted];


        [tempArray addObject:course];
        [course release];
        course = nil;

    }    

    self.courses = tempArray;
    [tempArray release];

    [self.tableView reloadData];    

    [super viewWillAppear:animated];
}

РЕДАКТИРОВАТЬ: Вот журнал ошибок:

Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[UIDeviceWhiteColor _id]: unrecognized selector sent to instance 0x4d2e2a0'
Call stack at first throw:
(
    0   CoreFoundation                      0x010435a9 __exceptionPreprocess + 185
    1   libobjc.A.dylib                     0x01197313 objc_exception_throw + 44
    2   CoreFoundation                      0x010450bb -[NSObject(NSObject) doesNotRecognizeSelector:] + 187
    3   CoreFoundation                      0x00fb4966 ___forwarding___ + 966
    4   CoreFoundation                      0x00fb4522 _CF_forwarding_prep_0 + 50
    5   BookApp                             0x000079e8 -[CoursesCategoriesViewController viewWillAppear:] + 184
    6   UIKit                               0x0017c9be -[UINavigationController _startTransition:fromViewController:toViewController:] + 858
    7   UIKit                               0x0017732a -[UINavigationController _startDeferredTransitionIfNeeded] + 266
    8   UIKit                               0x0017e562 -[UINavigationController pushViewController:transition:forceImmediate:] + 932
    9   UIKit                               0x001771c4 -[UINavigationController pushViewController:animated:] + 62
    10  BookApp                             0x000056d6 -[CoursesViewController tableView:didSelectRowAtIndexPath:] + 374
    11  UIKit                               0x00135b68 -[UITableView _selectRowAtIndexPath:animated:scrollPosition:notifyDelegate:] + 1140
    12  UIKit                               0x0012bb05 -[UITableView _userSelectRowAtPendingSelectionIndexPath:] + 219
    13  Foundation                          0x0084579e __NSFireDelayedPerform + 441
    14  CoreFoundation                      0x010248c3 __CFRUNLOOP_IS_CALLING_OUT_TO_A_TIMER_CALLBACK_FUNCTION__ + 19
    15  CoreFoundation                      0x01025e74 __CFRunLoopDoTimer + 1220
    16  CoreFoundation                      0x00f822c9 __CFRunLoopRun + 1817
    17  CoreFoundation                      0x00f81840 CFRunLoopRunSpecific + 208
    18  CoreFoundation                      0x00f81761 CFRunLoopRunInMode + 97
    19  GraphicsServices                    0x012d81c4 GSEventRunModal + 217
    20  GraphicsServices                    0x012d8289 GSEventRun + 115
    21  UIKit                               0x000ccc93 UIApplicationMain + 1160
    22  BookApp                             0x00001ff9 main + 121
    23  BookApp                             0x00001f75 start + 53
)

terminate called after throwing an instance of 'NSException'

Ответы [ 2 ]

1 голос
/ 14 июня 2011

Из вашей трассировки стека интересные части:

Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[UIDeviceWhiteColor _id]: unrecognized selector sent to instance 0x4d2e2a0'

и

5 BookApp 0x000079e8 - [CoursesCategoriesViewControllerviewWillAppear:] + 184

, что соответствует:

- (void)viewWillAppear:(BOOL)animated {
    //... 
    NSString *sqlQuery =
   [NSString stringWithFormat:
      @"SELECT co.name, co.id, o.location FROM course as co JOIN categories as ca JOIN occasions as o WHERE co.catID = ca.id AND co.catID = %i AND o.courseID = co.id",
      self.selectedCategory._id]; // << The culprit
    //... 

Вы получаете это, потому что self.selectedCategory._id пытается отправить сообщение _id на self.selectedCategory и не удается, self.selectedCategory не очень хороший тип.

Как это могло быть возможно?

Так как, я думаю, вы уверены, что self.selectedCategory - ожидаемый тип ...

Простопотому что self.selectedCategory был освобожден, и его адрес был повторно использован для другой переменной ... другого типа, в вашей трассировке экземпляр UIColor ... Может быть что-то еще.

Заключение

Дважды проверьте retain / release этого self.selectedCategory свойства:)

Примечание

+ 1 для предложения FMDB ... Обязательно!

1 голос
/ 14 июня 2011

Ваш код пропускает память.Вы не помещаете релиз после назначения временного массива в self.courses.Также вы не освобождаете объект курса после добавления его во временный массив.Для операций SQLite я предлагаю вам использовать FMDB.Управлять ими будет проще, чем помещать запросы SQL в каждый контроллер представления для извлечения данных из базы данных.Также это плохая практика, чтобы следовать такой схеме.Используйте FMDB для всех ваших целей sqlite.Создайте отдельный класс для всех коммуникаций sqlite.

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