2012-03-13 69 views
0

我对客观C非常陌生,我只是在学习。我做了techotopia教程“An_Example_SQLite_based_iOS_4_iPhone_Application_(Xcode_4)”,然后试着用FMDB再次实现它。 (我会发布链接到教程,但它让我只发布2链接最大)这个实例对象为什么被改变?

问题:在initWithFrame我创建eventDB。然后在addEvent,按下键后,eventDB.database的内容被改变。 ThiseventDBinitWithFramethis是否在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 

使用GDB我通过踩,发现它在main.m(由XCode4自动生成的)改变这里:(真的不知道该代码做什么,或者为什么它的存在)

#import <Cocoa/Cocoa.h> 

int main(int argc, char *argv[]) 
{ 
    return NSApplicationMain(argc, (const char **)argv); 
} 

我不熟悉目标C.有人可以帮我弄清楚为什么我的eventDB.database对象正在改变?我可能没有正确地管理一些内存,或者完全误解你应该如何做到这一点。任何帮助,将不胜感激。

eventDB是一个实例:

#import <Foundation/Foundation.h> 
#import "FMDatabase.h" 

@interface appTrackerDB : NSObject { 
    NSString *name; 
    NSString *address; 
    NSString *phone; 
    NSString *status; 
    NSString *databasePath; 
    FMDatabase *database; 
} 

谢谢!

而且[eventDB SAVEDATA]是:

- (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; 
} 
+0

你不想让它改变吗?我的意思是你在调用addEvent时设置名称和地址属性,这会改变对象。 或者你是在谈论替换对象? (例如,指针值改变) 也许你应该详细说明你的问题实际上是什么。 – robustus 2012-03-13 20:44:37

+0

我不希望'eventDB.database'的内容改变。我不会改变这些。 – user1267383 2012-03-13 20:51:48

+0

aehm ...那么[eventDB saveData]是什么;如果它没有把数据保存到数据库中呢? – robustus 2012-03-13 20:55:46

回答

0

其实你不保留数据库。在Objective-C中,您需要手动保留对象,尤其是如果它们不属性。 (例如,name被宣布为属性,database不是)

保留意味着您拥有该对象。 databaseWithObject保留数据库,但在其上调用autorelease,这通常意味着它将在调用方法完成后尽快删除引用。

根据您的平台,例如OS X而不是iOS,您可以启用GarbageCollection -feature。这意味着,OSX/Objective-C环境将为您执行大量的内存管理。但为了这个目的,你需要声明相关的实例变量作为属性对它们使用适当的setter和getter方法。

这里是一个属性声明的例子(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。米

@implementation appTrackerDB 
@synthesize name,address,status,phone; 
@synthesize databasePath,database; 

你会改为调用的你手动分配一个例子setter方法是:

  • [self setDatabase:...];而不是分配一个值直接database = ...

setter方法等setVariableName和吸气剂像variableName 这样的方法是由@synthesize指令为您合成的。

+0

我用 属性@属性(保留,非原子)FMDatabase *数据库;' ,综合它,仍然问题依然存在。我必须现在手动保留它吗? – user1267383 2012-03-13 21:30:15

+0

你必须在init中调用'[self setDatabase:[FMDatabase databaseWithPath:path]];'而不是'database = ..'variant – robustus 2012-03-13 21:33:01

+0

这样做!谢谢。这有什么不同? – user1267383 2012-03-13 21:39:46