2010-03-01 59 views
1

我有一個名爲「CardSet」的類,其中包含一個用於容納「卡片」的NSMutableArray * cardSet,我將其擴展爲製作「DeckCards」。我想要「CardSet」有一個名爲「(void)addCard:(Card *)」(以及類似的方法「removeCard」)的方法。我想要「addCard」,以便如何訪問並設置cardSet。更好的是,我想使用「addCard」方法初始化cardSet。類文件 「CardSet.h」 記載:Objective-C ::使用方法更改對象

#import <Cocoa/Cocoa.h> 

#import <Card.h> 

@interface CardSet : NSObject { 

    NSMutableArray* cardSet; 

} 

-(id)init; 

-(NSMutableArray*)getCardSet; 

-(void)setCardSet:(NSMutableArray *)new_cardset; 

-(Card*)getCard:(NSInteger) index; 

**-(void)addCard:(Card*) new_card;** 

-(void)removeCard:(Card*) old_card; 

-(void)dealloc; 

@property (readwrite, retain, getter=getCardSet, setter=setCardSet) NSMutableArray* cardSet; 

@end 

和方法文件讀取:

#import "CardSet.h" 

@implementation CardSet 

-(id)init{ 
    if(self = [super init]){} //will add initialisations here later 
    return self; 
} 

-(NSMutableArray*)getCardSet{ 
    return cardSet; 
} 

-(void)setCardSet:(NSMutableArray *)new_cardSet{ 
    cardSet = new_cardSet; 
} 

-(Card*)getCard:(NSInteger)index{ 
    return [cardSet objectAtIndex:index]; 
} 

**-(void)addCard:(Card *)new_card{ 
    [cardSet addObject:new_card]; 
}** 

-(void)removeCard:(Card *)old_card{ 
    [cardSet removeObject:old_card]; 
} 

-(void)dealloc{ 
    [cardSet release]; 
    [super dealloc]; 
} 

@synthesize cardSet; 

@end 

這編譯就好了。我想用它的「addCard」方法初始化一個「DeckCards」實例52次。當我在DeckCards setter方法中調用addCard 52次並詢問其「cardSet」的大小時,我返回0.

這似乎是一個範圍或特權問題? 「addCard」方法是否具有setter特權?必須使用setter參數與返回和相應的成員類型相同?

[我可以通過在「DeckCard」之外創建一個NSMutableArray對象「deck_cards_temp」來解決上述問題,向其中添加52張卡片,並通過setter繼承「DeckCards」 CardSet」。這是不是很滿意!]

你有什麼建議?非常感謝您的幫助和耐心。

+0

你或許應該還顯示'DeckCards'源。 – 2010-03-01 01:53:54

+0

請注意,您可以通過縮進4個空格或單擊* code *按鈕來創建代碼塊。 – 2010-03-01 01:57:05

+1

您還應該將這些訪問器方法重命名爲符合KVC。有關完整列表,請參閱http://developer.apple.com/documentation/Cocoa/Conceptual/ModelObjects/Articles/moAccessorMethods.html;兩個你應該改變'getCardSet'(應該只是'cardSet')和'getCard:'(應該是'objectInCardSetAtIndex:')。如果有任何事情(包括未來某天)會觀察這個'cardSet'屬性,這將爲這些訪問器啓用自動KVO通知。 – 2010-03-01 02:04:43

回答

3

你永遠不會實際創建cardSet對象。你應該在你-init方法來創建它:

-(id)init 
{ 
    if(self = [super init]) 
    { 
     cardSet = [[NSMutableArray alloc] init]; 
    } 
    return self; 
} 

因爲你從來沒有真正創建磁盤陣列,所有-addCard:的呼叫被髮送給nil對象。

當您將一個數組傳遞給-setCardSet:時,您傳遞的是初始化數組,因此該數組不再爲零,並且-addCard:調用正常工作。

+0

感謝您的回覆。這實際上在腳本中有一定的評論 - 我不認爲你需要在init中實例化NSMutableArray,XCode只是告訴我該數組未被使用。我也說過,將一個數組傳遞給setter可以很好地工作,但它沒有吸引力。 – SK9 2010-03-01 06:49:39

+0

其實你說的有點不同......我會檢查出來的,你可能是對的! – SK9 2010-03-01 07:30:42

+0

如果你想使用它,你肯定需要實例化這個數組。在你爲cardSets實例變量賦值一個有效數組之前,它的值是'nil',所有到'nil'的消息都被忽略。其他一些答案提供了有關改進實施的信息,但缺乏初始化是您問題的核心。 – 2010-03-01 22:27:08

0

CardSet.h

#import <Cocoa/Cocoa.h> 

// For know we just need to know there is a class named "Card" being used but implemented later 
@class Card; 

@interface CardSet : NSObject { 
    NSMutableArray *cardSet; 
} 

// Here are the methods according to "correct" naming conventions 
- (Card *)cardAtIndex:(NSInteger)index; 
- (void)addCard:(Card *)card; 
- (void)removeCard:(Card *)card; 

// This will help us and forget about writing the setter/getter 
@property (nonatomic, retain) NSMutableArray *cardSet; 

@end 

CardSet.m

#import "CardSet.h" 
// Now we tell the compiler what "Card" is and what methods etc. it has 
#import "Card.h" 

@implementation CardSet 

@synthesize cardSet; 

- (id)init { 
    if (self = [super init]) { 
     // If we don't create the cardSet, how are we able to work with it!? 
     NSMutableArray *anArray = [[NSMutableArray alloc] init]; 
     self.cardSet = anArray; 
     [anArray release]; 
    } 
    return self; 
} 

- (Card *)cardAtIndex:(NSInteger)index { 
    return [cardSet objectAtIndex:index]; 
} 

- (void)addCard:(Card *)card { 
    [cardSet addObject:card]; 
} 

- (void)removeCard:(Card *)card { 
    [cardSet removeObject:card]; 
} 

- (void)dealloc { 
    [cardSet release]; 
    [super dealloc]; 
} 

@end 

正如Abizern已經指出:命名的數組一樣類是一件壞事。

+0

正如我在對NSResponder答案的評論中指出的那樣,在初始化方法中設置實例變量的值時,不應該使用訪問器。直接設置,就像我的答案一樣。 – 2010-03-01 22:29:47

+0

哦,你是對的。感謝您指出了這一點。那麼這是否意味着訪問器沒有在init方法中正確設置?什麼時候使用它們是安全的? – bddckr 2010-03-02 11:09:24

0

我會縮短該init方法:

- (id)init { 
    if (self = [super init]) { 
     // If we don't create the cardSet, how are we able to work with it!? 
     self.cardSet = [NSMutableArray array]; 
    } 
    return self; 
} 
+0

您通常應該避免在初始化器中使用存取器方法。只需直接設置伊娃。 – 2010-03-01 22:28:12