Почему мое приложение падает - PullRequest
0 голосов
/ 20 сентября 2010

Я сделал класс. Это файл h.

//  MyClass.h
#import <Foundation/Foundation.h>


@interface MyClass : NSObject <NSCoding> {
    NSString *string1;
    NSString *string2;

}
@property (nonatomic, retain) NSString *string1;
@property (nonatomic, retain) NSString *string2;

@end

Это файл m

//  MyClass.m
#import "MyClass.h"


@implementation MyClass
@synthesize string1, string2;

- (void)encodeWithCoder:(NSCoder *)coder;
{
    NSLog(@"encodeWithCoder");

        [coder encodeObject:string1 forKey:@"string1"];
        [coder encodeObject:string2 forKey:@"string2"]; 


}

- (id)initWithCoder:(NSCoder *)coder;
{
    NSLog(@"initWithCoder");
    self = [super init];

        self.string1 = [coder decodeObjectForKey:@"string1"];
        self.string2 = [coder decodeObjectForKey:@"string2"];


    return self;
}


- (void)dealloc {

    [string1 release];
    [string2 release];
    [super dealloc];
}


@end

Я создал массив таких объектов, как этот

MyClass *object1 = [[MyClass alloc] init];
object1.string1 = @"object1 string1";
object1.string2 = @"string1 string2";
MyClass *object2 = [[MyClass alloc] init];
object2.string1 = @"object2 string1";
object2.string2 = @"object2 string2";
theArray = [[NSMutableArray alloc] initWithObjects:object1, object2, nil];

Тогда я сохранил массив вот так

[[NSUserDefaults standardUserDefaults] setObject:[NSKeyedArchiver archivedDataWithRootObject:theArray] forKey:@"savedArray"];

Затем я загрузил массив с диска следующим образом.

NSData *theData = [[NSUserDefaults standardUserDefaults] objectForKey:@"savedArray"];
if (theData != nil) {
    NSLog(@"found something");
    theArray = [NSMutableArray arrayWithArray:[NSKeyedUnarchiver unarchiveObjectWithData:theData]];
}

Программа работает нормально без ошибок, пока не дойдет до этого

DetailViewController *detailViewController = [[DetailViewController alloc] initWithNibName:@"DetailViewController" bundle:nil];
     // ...
     // Pass the selected object to the new view controller.
     detailViewController.myObject = [theArray objectAtIndex:indexPath.row];

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

Когда происходит сбой, это то, что говорит отладчик

*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[NSCFString objectAtIndex:]: unrecognized selector sent to instance 0x5955e50'
*** Call stack at first throw:
(
    0   CoreFoundation                      0x02395919 __exceptionPreprocess + 185
    1   libobjc.A.dylib                     0x024e35de objc_exception_throw + 47
    2   CoreFoundation                      0x0239742b -[NSObject(NSObject) doesNotRecognizeSelector:] + 187
    3   CoreFoundation                      0x02307116 ___forwarding___ + 966
    4   CoreFoundation                      0x02306cd2 _CF_forwarding_prep_0 + 50
    5   custom object array save test       0x00002872 -[RootViewController tableView:didSelectRowAtIndexPath:] + 156
    6   UIKit                               0x0032b718 -[UITableView _selectRowAtIndexPath:animated:scrollPosition:notifyDelegate:] + 1140
    7   UIKit                               0x00321ffe -[UITableView _userSelectRowAtIndexPath:] + 219
    8   Foundation                          0x00038cea __NSFireDelayedPerform + 441
    9   CoreFoundation                      0x02376d43 __CFRUNLOOP_IS_CALLING_OUT_TO_A_TIMER_CALLBACK_FUNCTION__ + 19
    10  CoreFoundation                      0x02378384 __CFRunLoopDoTimer + 1364
    11  CoreFoundation                      0x022d4d09 __CFRunLoopRun + 1817
    12  CoreFoundation                      0x022d4280 CFRunLoopRunSpecific + 208
    13  CoreFoundation                      0x022d41a1 CFRunLoopRunInMode + 97
    14  GraphicsServices                    0x02bfa2c8 GSEventRunModal + 217
    15  GraphicsServices                    0x02bfa38d GSEventRun + 115
    16  UIKit                               0x002c7b58 UIApplicationMain + 1160
    17  custom object array save test       0x00002160 main + 102
    18  custom object array save test       0x000020f1 start + 53
    19  ???                                 0x00000001 0x0 + 1
)
terminate called after throwing an instance of 'NSException'

Edit:

Мне удалось исправить проблему, заменив эту строку

theArray = [NSMutableArray arrayWithArray:[NSKeyedUnarchiver unarchiveObjectWithData:theData]];

с этой линией

theArray = [[NSMutableArray alloc] initWithArray:[NSKeyedUnarchiver unarchiveObjectWithData:theData]];

так что я думаю, теперь вопрос в том, почему это решило проблему?

1 Ответ

2 голосов
/ 20 сентября 2010

Я не вижу ничего плохого в вашем коде архивации / разархивирования. Я подозреваю, что indexPath.row вне диапазона.

РЕДАКТИРОВАТЬ после ОП отредактированный вопрос:

Сообщение об ошибке гласит: -[NSCFString objectAtIndex:]: unrecognized selector sent to instance 0x5955e50

Вы заметите, что это означает, что theArray фактически указывает на строку NSString. Где-то вы присвоили неправильную вещь своей переменной 'theArray'.

ИЗМЕНИТЬ снова после другого редактирования OP:

В исходном коде вы использовали alloc/initWithArray: вместо arrayWithArray:.

Использование arrayWithArray: не сработало для вас, потому что этот метод возвращает автоматически выпущенный объект. Так что к тому времени, когда вы использовали его позже, эта ссылка могла указывать практически на что угодно, и, следовательно, в одном случае она указывала на строку.

...