iOS-Analysis of Card Game project

Card.h

1
2
@property (strong, nonatomic) NSString *contents; 
//generate getters and setters for the properties

All objects are in heap, objective-c will manage all storage for you,

  • strong means keep the memory for this as long as anyone has a strong pointer to it, as soon as no sttong pointer, remove it, it is called “reference counting”;

  • weak means no strong pointer to it, set it to nil.

  • nonatomic means not thread safe

1
2
3
4
@property (nonatomic, getter=isChosen) BOOL chosen; 
// rename the getter
@property (nonatomic, getter=isMatched) BOOL matched;
// they don't need strong, because they are primitive type and don't stored in heap, no memory to manage, still have nonatomic, because we want getter and setter to be simple, don't have any locking code

Why do we need getter and setter?

Bound checking, side effect say update UI when we set the property, manage memory.

viewController.m

1
@property (weak, nonatomic) IBOutlet UILabel *scoreLabel;

@property created by this process is weak because the MVC’s View already keeps a strong pointer to the UILabel, so there’s no need for the Controller to do so as well. And if the UILabel ever left the View, the Controller most likely wouldn’t want a pointer to it anyway (but if you did want to keep a pointer to it even if it left the View, you could change this to strong (very rare)).

IBOutlet is a keyword Xcode puts here (similar to IBAction) to remind Xcode that this is not just a random @property, it’s an outlet

1
@property (strong, nonatomic) IBOutletCollection(UIButton) NSArray *cardButtons;

Outlet Collection arrays are always strong While the View will point strong, so Xcode has removed that option from the dialog. While the view will point strongly to all of the buttons inside the array, it will not point to the array itself at all(only our Controller will) so our outlet needs to be strongly held in the heap by our Controller. This is now an NSArray which contains all UIButtons you connected in random order. This randomness is okay for our purposes because the order of these cards will mean nothing to our matching game. It is something to consider though if you are developing an app where the order does matter (in that case, an outlet collection may not be what you want).

1
2
3
4
5
- (IBAction)touchCardButton:(UIButton *)sender {
NSUInteger choseButtonIndex = [self.cardButtons indexOfObject: sender];
[self.game chooseCardAtIndex: choseButtonIndex];
[self updateUI];
}

This method’s return type is actually, but Xcode uses the typedef IBAction instead just so that Xcode can keep track that this is not just a void random method that returns void, but rather, it’s an action method. Apart from that, IBAction is exactly the same thing as void.

Deck.m

1
@property (strong, nonatomic) NSMutableArray *cards;

Declaring a @property makes space in the instance for the pointer itself allocate space in the heap for the, but does not object the pointer points

1
2
3
4
-(NSMutableArray *)cards{
if(!_cards) _cards = [[NSMutableArray alloc] init];
return _cards;
}

If we send message to nil, nothing will happened, no error will happen, just return 0.
Lazy instantiation: initialise until we need to use.

PlayingCard.m

1
2
3
+(NSArray *)validSuits {
return @[@"♣", @"♦", @"♥", @"♠"];
}

A plus method is a class method, send message to class, not to instance of an object. Careating things, like string format; utility method like this, return constance(Usually these are either creation methods(like alloc or stringWithFormat: or utility methods.)