2012-06-25 37 views
0

這是我第一次使用這個網站,我很新的Objective-c。我確信這是一個簡單的問題,但由於某種原因,我遇到了很多問題。該應用程序旨在讓用戶通過文本字段輸入一個字符串,然後它將選擇句子的其餘部分並顯示它。問題似乎是,我的*名稱將在鍵盤方法後保留,並在changelabel方法中工作一次。然後,如果我再次按下按鈕,調用changelabel方法,名稱似乎已被釋放並崩潰應用程序。 #進口 #進口「Array.h」NSString工作一次然後不工作

@interface RandomBoredViewController : UIViewController { 
UILabel *label; 
UIButton *button; 
UITextField *textField; 
Array *array; 
NSString *name; 
NSString *description; 
NSMutableString *whole; 
} 
@property (nonatomic, retain) IBOutlet UILabel *label; 
@property (nonatomic, retain) IBOutlet UIButton *button; 
@property (nonatomic, retain) IBOutlet UITextField *textField; 
@property (nonatomic, retain) Array *array; 
@property (nonatomic, retain) NSString *name; 
@property (nonatomic, retain) NSString *description; 
@property (nonatomic, retain) NSMutableString *whole; 

-(IBAction) keyBoard; 
-(IBAction) changeLabel; 

@end 

和我的.m

#import "RandomBoredViewController.h" 

@implementation RandomBoredViewController 

@synthesize label; 
@synthesize checker; 
@synthesize button; 
@synthesize textField; 
@synthesize array; 
@synthesize name; 
@synthesize description; 
@synthesize whole; 


-(IBAction) changeLabel { 
NSLog(@"Button being pushed"); 
description = [array getString]; 
NSLog(@"%@",description); 
NSLog(@"%@",name); 
name = [NSString stringWithString:name]; 
whole = [NSMutableString stringWithString:name]; 
NSLog(@"%@",name); 
NSLog(@"%@",whole); 
[whole appendString:description]; 
NSLog(@"%@",name); 
NSLog(@"%@",whole); 
label.text = whole; 
NSLog(@"%@",name); 
} 

-(IBAction) keyBoard { 
name = [NSString stringWithString:textField.text]; 
NSLog(@"%@",name); 
label.text = [NSString stringWithString: name]; 
[textField resignFirstResponder]; 
} 

- (void)viewDidLoad { 
[super viewDidLoad]; 
array = [[Array alloc]init]; 
[array createArray]; 
NSLog(@"%i",[array arrayCount]); 
whole = [[NSMutableString alloc]init]; 
name = [[NSString alloc]init]; 
} 

- (void)dealloc { 
[super dealloc]; 
[label release]; 
[button release]; 
[textField release]; 
[array release]; 
//[name release]; 
[description release]; 
} 

@end 
+0

這行看起來有點多餘:'name = [NSString stringWithString:name];'它可能是你的錯誤的根源。 –

回答

1

以微觀世界爲例,您發佈的代碼創建了兩個名爲name的事物 - 一個實例變量和一個屬性。

實例變量是直接訪問存儲。他們沒有行爲。

屬性是通過獲取者和設置者訪問的命名屬性。所以他們可能會有任意的行爲。他們可能會報告實例變量的值或從實例變量計算出的值或通過任何其他方式計算或獲取的值。相關地,制定者可以是retain,assign或以任何其他方式行事。

實例變量只能由它們所屬類的實例訪問。屬性通常旨在被任何人訪問。

由於保留是一種行爲,您已將它歸於您的name屬性,因此設置某些值會導致retain。實例變量不能有行爲,因此設置一個值不會導致retain或其他任何內容。

其結果是,這條線:

name = [NSString stringWithString:name]; 

創建新的字符串並返回一個非所屬參考。這意味着它肯定會持續這個autorelease池的持續時間(也就是說,如果你沒有手動控制你的autorelease池,你明確可以將它作爲參數傳遞或安全地返回它)。

您將該引用存儲到您的實例變量中。實例變量沒有行爲,因此引用被存儲,但您仍然不擁有該對象。在自動釋放池的使用期限內使用它仍然是安全的。

因此,當您在該方法中訪問它時,它是安全的。當您稍後訪問時,它不安全。

相反,如果你已經走了有:

self.name = [NSString stringWithString:name]; 

然後你必須設置該字符串是該屬性的新值。因爲你的財產具有retain行爲,所以你可以完全安全地訪問字符串對象,除非你另有說明。

由於您擁有與實例變量名稱完全相同的屬性,因此您可以隨後以nameself.name的身份訪問它。同樣,如果您確保手動獲得了擁有的引用,則可以將其直接存儲到實例變量中,而不是通過屬性。

如上所述,使用ARC是一種讓編譯器爲你計算所有這些東西的方法。

這個問題是什麼導致你的代碼崩潰 - 你最終試圖訪問一個不再有效的引用。如果你擁有它,那麼至少只要你保有所有權,它就會繼續存在。

+0

非常感謝您的幫助。這深入的描述正是我需要修復我的應用程序並理解語言。這真的是我第一次在網上發佈這樣的內容,並且很高興知道我的問題被認真對待並且沒有受到拖延。再次謝謝你。 –

0

嘗試使用self.name 有時候這個東西混淆了我也和你可能要考慮使用弧,在這種情況下,大部分東西都可以避免。

當使用屬性時,您應該始終使用self.propertyName vs propertyName(only),它使用訪問器(get propertyName,set propertyName)而不是直接訪問指針值。

請記住規則有2個例外,init和dealloc不應該使用self。

self.name = [NSString stringWithString:name]; 

技術上你也應該有一個init方法 初始化變量,我相信你應該調用[超級的dealloc]最後不是第一次在你的dealloc方法,但是那不是你的問題,可能沒有關係(只是我做什麼時,我不使用弧)

+0

'self.'東西很好,但變量在'viewDidLoad'中被初始化了,不需要'再次'初始化它們。 –

+0

是的,但那不是他們想要初始化的地方。但是,對於較小/較簡單的項目,這可能並不重要 –

+0

爲什麼它們不是「假定要初始化」的。看起來和其他地方一樣好。實際上,調用像'self.name = [NSString stringWithString:@「anything」];'會照顧''synthesize'創建的setter中的'init',我相信。 –

3

您正在設置名稱爲NSString的自動釋放實例,這可能是什麼導致您的應用程序崩潰。

使用

self.name = [NSString stringWithString:textField.text]; 

你合成的突變會保留的NSString,並防止它被釋放。

+0

謝謝,這是一個即時修復。非常感謝你花時間看這個。我確信這是你最容易解決的問題之一,但它非常有幫助。 –

+0

很高興能幫到你! –

0

當您在changeLabel中更改您的實例變量時,您應該釋放以前的值並保留新值。您可以使用訪問器爲您執行內存管理。另外,我認爲你應該調用[super dealloc]之後在你的實現dealloc中釋放實例變量。

如果你不熟悉可可內存管理(即使你是),最好的方法是啓用ARC(自動引用計數)並讓編譯器處理它。

+0

謝謝。我看着ARC,它看起來很棒,但我仍然在運行雪豹,無法運行xcode 4.但是,謝謝 –

相關問題