It is because the object you appear to be dearchiving is a pointer to an object of class UserKeys
, rather than an object that is or descends from NSArray. When -initWithAray:
hits your oldArray pointer to UserKeys
, it doesn't know, or doesn't care what class it is, it simply sends it a -count
message so as to ascertain the size it must grow to.
Loading NSTableView from unarchived data
-
10-03-2022 - |
Question
I'm trying to implement saving of user preferences in my OS X app. I have an NSTableView which stores its data to my .plist
file, but I have troubles loading same data back to my NSTableView.
My model object:
#import <Foundation/Foundation.h>
@interface UserKeys : NSObject <NSCoding>
@property (nonatomic, copy) NSString *userKeyName;
@property (nonatomic, copy) NSString *userApi;
@property (nonatomic, copy) NSString *userCode;
@end
and its implementation:
#import "UserKeys.h"
@implementation UserKeys
- (id)init
{
self = [super init];
if (self) {
//
}
return self;
}
- (id)initWithCoder:(NSCoder *)aDecoder {
self = [super init];
if (self) {
self.userKeyName = [aDecoder decodeObjectForKey:@"userKeyName"];
self.userApi = [aDecoder decodeObjectForKey:@"userApi"];
self.userCode = [aDecoder decodeObjectForKey:@"userCode"];
}
return self;
}
- (void)encodeWithCoder:(NSCoder *)enCoder {
[enCoder encodeObject:self.userKeyName forKey:@"userKeyName"];
[enCoder encodeObject:self.userApi forKey:@"userApi"];
[enCoder encodeObject:self.userCode forKey:@"userCode"];
}
@end
My preferences view controller header:
#import <Cocoa/Cocoa.h>
#import "MASPreferencesViewController.h"
#import "UserKeys.h"
@interface PreferencesApiKeysViewController : NSViewController <MASPreferencesViewController>
@property (strong) NSMutableArray *allKeys;
@end
and its implementation:
#import "PreferencesApiKeysViewController.h"
#import "UserKeys.h"
@interface PreferencesApiKeysViewController ()
@property (weak) IBOutlet NSTableView *keysTableView;
@end
@implementation PreferencesApiKeysViewController
- (id)initWithNibName:(NSString *)nibName bundle:(NSBundle *)bundle {
if ((self = [super initWithNibName:nibName bundle:bundle])) {
self.allKeys = [NSMutableArray array];
}
return self;
}
// delegating....
//
- (void)viewWillAppear {
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSData *data = [defaults objectForKey:@"UserKeys"];
if (data != nil) {
NSArray *oldArray = [NSKeyedUnarchiver unarchiveObjectWithData:data];
if (oldArray != nil) {
self.allKeys = [[NSMutableArray alloc] initWithArray:oldArray];
} else {
self.allKeys = [NSMutableArray array];
}
}
}
- (NSView *)tableView:(NSTableView *)tableView viewForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row {
// some code...
return cellView;
}
- (NSInteger)numberOfRowsInTableView:(NSTableView *)tableView {
return [self.allKeys count];
}
The error I'm getting is:
-[UserKeys count]: unrecognized selector sent to instance 0x100534df0
When I put a breakpoint in - (void)viewWillAppear
, I can see that data
has around 250 bytes, but this oldArray
seems to be empty. I understand that I'm doing some major mistake here with self.allKeys
so that my table is not aware how many rows it should create, but after lots of attempts to get proper data, I'm really out of ideas why is this happening.
So, how to properly unarchive my data and present it in NSTableView?
(I'm using Xcode 4.6)
Solution