2012-03-13 121 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

相關問題