0

Я сделал класс. Это файл 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 

Это м файл

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

с этим liine

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

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

+0

Что такое авария в точности? Есть ли смысл в консоли? Когда вы получаете массив из пользовательских значений по умолчанию, это тот размер, который вы ожидаете? – imaginaryboy

+0

Я отредактировал мое сообщение, чтобы показать сообщение об ошибке. Во всяком случае, я смог исправить код, но не полностью понял решение.Должен ли я ответить на свой вопрос, показывая решение, или ждать, пока кто-то еще это выяснит, и, может быть, даст лучшее объяснение? –

ответ

2

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

EDIT после OP отредактированный вопрос:

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

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

EDIT снова после того, как другой О.П. редактирования:

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

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

+0

Нет, это не так. Когда вы посмотрели на него, ошибок не было. Я исправил код выше, чтобы он отображал ошибку. Я был в состоянии исправить это, потому что у меня был код для копирования, но я не совсем понял это решение. Мне интересно, если я должен ответить на свой вопрос или подождать и посмотреть, сможет ли кто-то другой понять это и, может быть, объяснить то, что я не понимаю. –

+0

@awakeFromNib: Если ваше решение сработало, по крайней мере, опубликуйте его в OP, чтобы другие могли хотя бы увидеть решение в будущем, даже если объяснение никогда не возникает. – AndyG

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