#ios #objective-c
#iOS #objective-c
Вопрос:
Student.h
#import <Foundation/Foundation.h>
#import "Subject.h"
@interface Student : NSObject <NSCoding> {
NSString *studentID;
NSString *studentName;
NSMutableArray<Subject* > *subjects;
}
@property (copy) NSString *studentID;
@property (copy) NSString *studentName;
@property (copy) NSMutableArray<Subject* > *subjects;
-(Student *)initWithStudentID:(NSString *)ID andStudentName:(NSString *)name;
-(void)addSubject:(Subject *) subject;
@end
Student.m
#import "Student.h"
@implementation Student
@synthesize studentName;
@synthesize studentID;
@synthesize subjects;
-(Student *)initWithStudentID:(NSString *)ID andStudentName:(NSString *)name {
Student *student = [[Student alloc] init];
student.studentID = [NSString stringWithString:ID];
student.studentName = [NSString stringWithString:name];
return student;
}
-(void)addSubject:(Subject *)subject{
if(subjects==nil){
subjects=[[NSMutableArray alloc]init];
}
[subjects addObject:subject];
}
- (id)initWithCoder:(NSCoder *)aDecoder {
if (self = [super init]) {
[self setStudentID:[aDecoder decodeObjectForKey:@"studentID"]];
[self setStudentName:[aDecoder decodeObjectForKey:@"studentName"]];
[[NSUserDefaults standardUserDefaults] setObject:[NSKeyedArchiver archivedDataWithRootObject:subjects] forKey:@"subjects"];
}
return self;
}
- (void)encodeWithCoder:(NSCoder *)aCoder {
[aCoder encodeObject:studentID forKey:@"studentID"];
[aCoder encodeObject:studentName forKey:@"studentName"];
[aCoder encodeObject:subjects forKey:@"subjects"];
}
@end
Subject.h
#import <Foundation/Foundation.h>
@interface Subject : NSObject
@property NSString *subjectID;
@property NSString *subjectName;
@end
Subject.m
#import "Subject.h"
@implementation Subject
@end
Main.m
#import <Foundation/Foundation.h>
#import "Student.h"
int main(int argc, const char * argv[]) {
@autoreleasepool {
Student *student1=[[Student alloc ]initWithStudentID:@"Nirmal" andStudentName:@"101"];
Subject *subject = [Subject alloc];
subject.subjectID=@"S01";
subject.subjectName=@"PHY";
[student1 addSubject:subject];
[NSKeyedArchiver archiveRootObject:student1 toFile:@"/Users/kuzhandaivel/Documents/nirmal.plist"];
Student *student2=[NSKeyedUnarchiver unarchiveObjectWithFile:@"/Users/kuzhandaivel/Documents/nirmal.plist"];
NSLog(@"%@",student2.studentID);
NSLog(@"%@",student2.studentName);
NSLog(@"%@",[student2.subjects description]);
}
return 0;
}
Как сохранить NSMutableArray, присутствующий в классе, в файл?
Вышеупомянутая программа выдает приведенную ниже ошибку в строке:
[aCoder encodeObject:subjects forKey:@"subjects"];
encodeWithCoder
функция at присутствует в файле student.m.
Архиватор [4667:102276] -[Subject encodeWithCoder:]: нераспознанный селектор, отправленный экземпляру 0x1006000a0 2016-10-22 20:25:57.738 Архиватор [4667:102276] *** Завершение работы приложения из-за неперехваченного исключения 'NSInvalidArgumentException', причина: '-[Subject encodeWithCoder:]: нераспознанный селектор, отправленный экземпляру 0x1006000a0' *** Первый стек вызовов throw:
Ответ №1:
Subject
также должно соответствовать NSCoding
протоколу точно так же, как Student
.
Каждый класс, хранящийся в корневом объекте, который вы архивируете, должен соответствовать NSCoding
протоколу.
Комментарии:
1. @тема интерфейса: NSObject<NSCoding>. Я добавил таким образом. должен ли я добавить функции initWithCoder и encodeWithCoder в файл Subject.m? Пожалуйста, посоветуйте
2. ДА. Два метода требуются для каждого класса, который заявляет, что он соответствует
NSCoding
протоколу.3. Спасибо за rMaddy. Я попробую это сейчас!!
4. Не могли бы вы, пожалуйста, сказать мне, как сохранить NSDecimalNumber в файл. Для строки —> @property NSDecimalNumber *miles я пишу как self.miles = [кодировщик decodeObjectForKey:@»miles»] в методе initWithCoder и [Кодировщик encodeObject:_miles forKey:@»miles»] в методе encodeWithCoder. Но данные не сохраняются в файле plist. Пожалуйста, посоветуйте
Ответ №2:
Все объекты внутри вашей иерархии объектов должны подтвердить протокол NSCoding, чтобы иметь возможность сохранять в архив.
Если вы видите класс NSString
@interface NSString : NSObject
<NSCopying, NSMutableCopying,NSSecureCoding
>
Он реализует NSSecureCoding, который является подклассом NSCoding. Итак, вам нужно реализовать протокол NSCoding для всех дочерних объектов и дочернего объекта дочернего объекта и так далее. В основном он перебирает все дочерние объекты и кодирует их один за другим. Таким образом, произойдет сбой, если вы не внедрили ни в одном из них.
Архиватор [4667: 102276] -[Subject encodeWithCoder:]: нераспознанный селектор, отправленный экземпляру 0x1006000a0 2016-10-22 20:25:57.738 Архиватор [4667:102276] * Завершение работы приложения из-за неперехваченного исключения ‘NSInvalidArgumentException’, причина: ‘-[Subject encodeWithCoder:]: нераспознанный селектор, отправленный экземпляру 0x1006000a0’ * Стек вызовов первого броска:
Я думаю, что в этой строке сказано все.
[тема encodeWithCoder:(NSCoder *)aCoder]
Комментарии:
1. Привет, не могли бы вы, пожалуйста, рассказать мне, как сохранить NS
2. Не могли бы вы, пожалуйста, сказать мне, как сохранить NSDecimalNumber в файл. Для строки —> @property NSDecimalNumber *miles я пишу как self.miles = [кодировщик decodeObjectForKey:@»miles»] в методе initWithCoder и [Кодировщик encodeObject:_miles forKey:@»miles»] в методе encodeWithCoder. Но данные не сохраняются в файле plist. Пожалуйста, посоветуйте
3. Он должен нормально работать как NSDecimalNumber-> NSNumber-> NSValue-> NSObject. Это иерархия классов, и она должна работать нормально. Единственное, что меня беспокоит, это то, что вам следует использовать self.miles, а не iVar, если вы установили средства доступа поверх него. Можете ли вы попробовать self.miles и проверить, работает ли он?