I am trying to incorporate encapsulation into my app (for an explanation of what this code is supposed to do, see here)... this is the code in Class 'A':
.h file
@interface ExportBookData : NSObject {
@public NSArray *booksArray;
@public NSMutableDictionary *builtFileList;
@public NSMutableArray *exportData;
}
- (id)initWithCategory: (NSString*) booksellerID;
@end
This is the code for the .m file:
.m file
@implementation ExportBookData
-(id)initWithCategory: (NSString*) booksellerID {
return (id)booksellerID;
}
@end
This is the beginning of the method in class 'B' (.m file) that uses the encapsulated data:
ExportBookData *abe = [[ExportBookData alloc] initWithCategory:@"ABE"];
abe->builtFileList = [NSMutableDictionary dictionary]; <- crash on this line
abe->exportData = [NSMutableArray arrayWithCapacity:abe->booksArray.count];
if(cbvABE.checked) {
I'm getting the following error on the 2nd line of code as indicated:
Since I'm a noob using encapsulation, I don't see what I've done wrong. I have followed several examples which are similar to my code; what am I doing wrong to cause this crash?
So many issues here.
First off, do not declare public instance variables. Use properties and only for values that you want other classes to have access to.
@interface ExportBookData : NSObject
@property(nonatomic, strong) NSArray *booksArray;
@property(nonatomic, strong) NSMutableDictionary *builtFileList;
@property(nonatomic, strong) NSMutableArray *exportData;
- (id)initWithCategory: (NSString*) booksellerID;
@end
Now your ExportBooksData init
method.
It needs to be:
-(id)initWithCategory: (NSString*) booksellerID {
self = [super init];
if (self) {
// do something with booksellerID
}
return self;
}
Every init
method of a base class should following this general pattern.
And now your other code is needlessly using ->
operator. Use the actual properties provided by the interface instead:
ExportBookData *abe = [[ExportBookData alloc] initWithCategory:@"ABE"];
abe.builtFileList = [NSMutableDictionary dictionary];
abe.exportData = [NSMutableArray arrayWithCapacity:booksArray.count];
But it makes no sense that external code is doing all of this. Let your class set itself up as needed. So now your init
method should be:
-(id)initWithCategory: (NSString*) booksellerID {
self = [super init];
if (self) {
self.builtFileList = [NSMutableDictionary dictionary];
self.exportData = [NSMutableArray arrayWithCapacity:booksArray.count];
// do something with booksellerID
}
return self;
}
Now your other code simply becomes:
ExportBookData *abe = [[ExportBookData alloc] initWithCategory:@"ABE"];
without the need to set the other properties.
There's a lot more you should be doing here (like making use of the booksellerID
and booksArray
) but this will get you started.