为什么要更改此实例对象?

时间:2012-03-13 20:39:39

标签: objective-c cocoa fmdb

我在目标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}}

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指令为您综合。