2013-02-16 48 views
0

嗯 我在目標c中有初始化類屬性時遇到一些麻煩。我已經閱讀了很多信息,但沒有找到對我的問題的答案。 所以我舉例說明。 1)關於目標c中的init屬性類

//Ex_1.h 
@interface Ex_1: UIView { 
    IBOutlet UIButton *playBut; 
} 

@property(retain, nonatomic) IBOutlet UIButton *playBut; 
-(void) method1; 

@end 

//Ex_1.m 
@implementation Ex_1 
@synthesize playBut; 

-(id) initWithFrame:(CGRect)frame { 
    self = [super initWithFrame : frame]; 
    if (self != nil) 
     playBut = [UIButton buttonWithType:UIButtonTypeRoundedRect]; //retainCount of playBut = 1; 
    return self; 

} 

-(void) method1 { 
    [playBut setTitle:@"pause" forState:UIControlStateNormal]; 
} 

@end 

我主要PROGRAMM我首先初始化Ex_1的對象,然後經過一些時間調用這個對象的方法1([對象方法1]),我得到運行時錯誤(錯誤告訴我,playBut是dealloc的,但我認爲playBut的保留數= 1)。 所以我有一些問題:

  1. 這有可能嗎?
  2. 爲什麼垃圾收集dealloces playBut如果保留計數= 1(因爲我不叫[playBut釋放〕;
  3. 如何初始化類屬性

我使用C familar ++和ActionScript,但我看到第一次在我的生活垃圾收集dealloced類屬性。 我使用非ARC。 這對我來說是很重要的。 感謝您的關注和解答。

+0

http://www.whentouseretaincount.com – vikingosegundo 2013-02-16 17:45:20

回答

2

[UIButton buttonWithType:]返回autoreleased對象。這將是活着爲了生命我稱之爲範圍,即initWithFrame:,但autorelease池可以在此之後回收它。而應該說,在你的初始化選擇:

playBut = [[UIButton buttonWithType:UIButtonTypeRoundedRect] retain]; 

然後在你的dealloc發送此:

[playBut release]; 

現在,如果你是到playBut作爲孩子添加到另一個UIView,這種觀點會保留孩子,只要你只在超級視圖的生命週期中使用它,你就不需要。這是一種正常模式。你可以走得更遠,並指定一個tag播放,然後使用viewWithTag:找到你的UIButton當你需要它。

+0

好的,謝謝。但是當我初始化對象時,我總是會獲得autoreleased對象?例如obj = [[Class alloc] init],是否返回自動釋放對象? – juramoshkov 2013-02-16 17:47:26

+0

如果你有'new','alloc init','retain'或'copy'(NARC)一個對象,你必須釋放它。當一個方法的名稱以任何這些單詞開始時,這意味着它是爲調用者創建的,調用者有責任在對象完成時釋放該對象。否則,返回的方法不是由調用方擁有(它是使用autorelease創建的),並且調用方必須通過在對象上調用retain來保留它。 – Jano 2013-02-16 17:56:34

+0

屬性IBOutlet用於鏈接該屬性與在界面構建器中創建的按鈕。在這種情況下,該按鈕已經被jeff所說的控制器視圖所保留,所以你會在你的屬性中寫'assign',而不是'retain'。另一件事,如果您使用的是現代版本的Xcode,則不需要實例變量或@synthesize,只需@property即可。 – Jano 2013-02-16 18:05:46

1

您可能會因爲您的財產聲明包含retain而感到困惑。然而,你直接到你這裏伊瓦爾分配:

 playBut = [UIButton buttonWithType:UIButtonTypeRoundedRect]; //retainCount of playBut = 1; 

所以沒有采取屬性setter的優勢,因此它不會保留你。

因此,要麼:

 self.playBut = [UIButton buttonWithType:UIButtonTypeRoundedRect]; 

或者:

 playBut = [[UIButton buttonWithType:UIButtonTypeRoundedRect] retain]; 

兩個,用self.playBut是更好 - 你應該使用屬性及其存取所有的時間,除非你有充分的理由不要。無需分別聲明iVar(或近來的@synthesize)。看到我的答案在這裏: Should I declare variables in interface or using property in objective-c arc?

至於你使用UIButtons的具體例子,他們通常會直接添加到用戶界面,它爲你保留,所以你不會遇到這種情況。這就是爲什麼IBOutlets通常被宣佈爲weak(ARC)或assign(nonARC)。

+0

因此,當我使用類屬性時,我應該使用self.property還是屬性(如C++)訪問它(我不談論初始化? – juramoshkov 2013-02-16 18:10:20

+0

@ user2078865 - 我假設你的意思是_instance_屬性。屬性,使用自我。[見我的答案在這裏的細節](http://stackoverflow.com/questions/14236799/should-i-declare-variables-in-interface-or-using-property-in-objective-c- arc/14236931#14236931) – foundry 2013-02-16 18:12:04

+0

是的,我的意思是實例屬性,好吧, – juramoshkov 2013-02-16 18:15:27