I have read Where to put iVars in "modern" Objective-C? and some other questions, but I am still confused.
I am reading from https://www.raywenderlich.com/913/sqlite-tutorial-for-ios-making-our-app SQLite Tutorial:
.h
#import <Foundation/Foundation.h>
#import <sqlite3.h>
@interface FailedBankDatabase : NSObject {
sqlite3 *_database;
}
+ (FailedBankDatabase*)database;
- (NSArray *)failedBankInfos;
@end
.m
#import "FailedBankDatabase.h"
#import "FailedBankInfo.h"
@implementation FailedBankDatabase
static FailedBankDatabase *_database;
+ (FailedBankDatabase*)database {
if (_database == nil) {
_database = [[FailedBankDatabase alloc] init];
}
return _database;
}
Please correct where I am wrong:
The sqlite3 * database
:
.h
fileAll meaning we can't access nor set it! Why are we doing this?
What what is the purpose of placing this in .h
file; Why not just
write as a property? Or just write in our .m
file alone?
Edit: What is the modern way of using Sqlite3 in Objective-C?
It was not always possible to declare instance variables in the implementation
block. It has been possible for several years, but the date of that tutorial is April 8, 2010. When it was written, the author probably wanted it to work on older versions of the compiler.
Because _database
is not declared @private
, it is in fact possible to access the instance variable outside of the FailedBankDatabase
implementation. In Objective-C, you can treat an object pointer as a struct pointer and access its instance variables like struct fields. So you could do this:
#import "FailedBankDatabase.h"
int main(int argc, char *argv[])
{
FailedBankDatabase *db = [FailedBankDatabase database];
printf("instance variable: %p\n", db->_database);
return 0;
}
That's probably a bad idea, though.
Since your sqlite3 *_database
is intended to be private, you probably just want to do this:
FailedBankDatabase.h
#import <Foundation/Foundation.h>
@class FailedBankInfo;
@interface FailedBankDatabase : NSObject
+ (FailedBankDatabase*)database;
- (NSArray<FailedBankInfo *> *)failedBankInfos;
@end
FailedBankDatabase.m
#import "FailedBankDatabase.h"
#import "FailedBankInfo.h"
#import <sqlite3.h>
@implementation FailedBankDatabase {
sqlite3 *_database;
}
static FailedBankDatabase *theInstance;
+ (FailedBankDatabase*)database {
if (theInstance == nil) {
theInstance = [[FailedBankDatabase alloc] init];
}
return theInstance;
}