我在目标C上很新,我只是在学习。我做了techotopia教程“An_Example_SQLite_based_iOS_4_iPhone_Application_(Xcode_4)”,然后尝试用FMDB再次实现它。 (我发布了教程的链接,但它让我只发布了2个链接)
问题:在initWithFrame
我创建eventDB
。然后在addEvent
中,在按键后,eventDB.database
的内容会发生变化。 eventDB
initWithFrame
addEvent
#import "appTracker.h"
@implementation appTracker
- (id) initWithFrame:(NSRect)frameRect
{
self = [super initWithFrame:frameRect];
eventDB = [[appTrackerDB alloc] init];
return self;
}
- (void) keyDown: (NSEvent *) event
{
NSString *chars = [event characters];
unichar character = [chars characterAtIndex: 0];
if (character == 'A') {
NSLog (@"Adding event");
[self addEvent:@"test_arg"];
}
}
- (void) addEvent: (NSString *) name
{
[eventDB setName:name];
[eventDB setPhone:name];
[eventDB setAddress:name];
[eventDB setStatus:name];
[eventDB saveData];
}
...
@end
main.m
#import <Cocoa/Cocoa.h>
int main(int argc, char *argv[])
{
return NSApplicationMain(argc, (const char **)argv);
}
。{/ 1}}
eventDB.database
使用GDB我逐步完成,发现它在eventDB
(由XCode4自动生成)中发生了变化:(不确定这段代码的作用或原因)
#import <Foundation/Foundation.h>
#import "FMDatabase.h"
@interface appTrackerDB : NSObject {
NSString *name;
NSString *address;
NSString *phone;
NSString *status;
NSString *databasePath;
FMDatabase *database;
}
我对目标C不熟悉。有人可以帮我弄清楚为什么我的- (void) saveData
{
[database executeUpdate:@"insert into user (name, address, phone) values(?,?,?)",
name, address, phone,nil];
}
对象被改变了吗?我可能没有正确管理一些内存或完全误解你应该如何做到这一点。任何帮助将不胜感激。
@implementation appTrackerDB
@synthesize name,address,status,phone;
- (id)init
{
self = [super init];
if (self) {
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *docsPath = [paths objectAtIndex:0];
NSString *path = [docsPath stringByAppendingPathComponent:@"database.sqlite"];
database = [FMDatabase databaseWithPath:path];
[database open];
[database executeUpdate:@"create table IF NOT EXISTS user(ID INTEGER PRIMARY KEY AUTOINCREMENT, NAME TEXT, ADDRESS TEXT, PHONE TEXT)"];
if ([database hadError]) {
NSLog(@"DB Error %d: %@", [database lastErrorCode], [database lastErrorMessage]);
}
name = @"TEST";
}
return self;
}
是以下的实例:
{{1}}
谢谢!
[eventDB saveData]也是:
{{1}}
用以下方法创建数据库:
{{1}}
答案 0 :(得分:0)
您实际上并未保留数据库。在Objective-C中,您需要手动保留对象,特别是如果它们不是属性。 (例如name
被声明为属性,database
不是)
保留意味着您拥有对象。 databaseWithObject
保留数据库但在其上调用autorelease
,这通常意味着它将在调用方法完成后尽快删除引用。
取决于您的平台,例如OS X而不是iOS,您可以启用 GarbageCollection -feature。这意味着,OSX / Objective-C环境将为您进行大量的内存管理。但是为了使它具有任何用途,您需要声明相关的实例变量,因为属性和对它们使用适当的setter-和getter-methods。
以下是属性声明( appTrackerDB.h )的示例:
#import <Foundation/Foundation.h>
#import "FMDatabase.h"
@interface appTrackerDB : NSObject {
/*
These are only necessary when
using iOS-Versions prior to
iOS 4, or if you really
need to manipulate the values
without utilizing the setter-/getter-
methods.
*/
NSString *name;
NSString *address;
NSString *phone;
NSString *status;
NSString *databasePath;
FMDatabase *database;
}
@property (retain) NSString *name,*address;
@property (retain) NSString *phone,*status,*databasePath;
@property (retain) FMDatabase *database;
appTrackerDB.m :
@implementation appTrackerDB
@synthesize name,address,status,phone;
@synthesize databasePath,database;
您将调用的示例setter方法代替您手动分配:
[self setDatabase:...];
而非直接分配值database = ...
像setVariableName
这样的Setter方法和variableName
之类的getter方法
由@synthesize
指令为您综合。