We have a lot of staff that are relatively new to iOS programming and memory management in general. I want to build an app with a couple of labels showing retain counts and a some buttons to increment and decrement those retain counts.
Does anyone know of anything out there already that would work or have any advice on setting this up so it will get my point across? I have a working version, but it doesn't seem to be working the way I think it should.
ViewController.h
#import <UIKit/UIKit.h>
@interface MemoryTestingViewController : UIViewController {
UILabel *retainCount;
UILabel *descLabel;
UIButton *addRetain;
UIButton *addRelease;
UIButton *access;
NSMutableString *myString;
}
@property (nonatomic, retain) IBOutlet UILabel *retainCount;
@property (nonatomic, retain) IBOutlet UILabel *descLabel;
@property (nonatomic, retain) IBOutlet UIButton *addRetain;
@property (nonatomic, retain) IBOutlet UIButton *addRelease;
@property (nonatomic, retain) IBOutlet UIButton *access;
@property (nonatomic, retain) NSMutableString *myString;
-(IBAction)pressedRetain:(id)sender;
-(IBAction)pressedRelease:(id)sender;
-(IBAction)pressedAccess:(id)sender;
@end
ViewController.m
-(IBAction)pressedAccess:(id)sender {
descLabel.text = @"Accessing myString, did we crash";
myString = [NSMutableString stringWithFormat:@"Accessing myString"];
retainCount.text = [NSString stringWithFormat:@"%i", [myString retainCount]];
}
-(IBAction)pressedRetain:(id)sender {
descLabel.text = @"Adding 1 to retain count for myString";
[myString retain];
retainCount.text = [NSString stringWithFormat:@"%i", [myString retainCount]];
}
-(IBAction)pressedRelease:(id)sender {
descLabel.text = @"Adding 1 release to myString";
[myString release];
retainCount.text = [NSString stringWithFormat:@"%i", [myString retainCount]];
}
- (void)didReceiveMemoryWarning
{
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
}
#pragma mark - View lifecycle
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad
{
// init our variable string
myString = [[NSString alloc] init];
descLabel.text = @"myString retain count after alloc/init";
// fill our label with myString's retain count starting out
retainCount.text = [NSString stringWithFormat:@"%i", [myString retainCount]];
[super viewDidLoad];
}
When this runs, it seems fine, but crashes whenever I try press the retain button. If anyone has any advice how to clean this up a bit, I would appreciate it. Ideally I would like them to press the access button when the retain count hits zero and have the app crash, but the access button should work as long as the retain count is 1 or better. Thanks.
The retainCount
of an object is tricky business.
If you were to continue down this path, you should be aware of the following details:
retainCount
can never return 0retain
/release
/autorelease
won't work as some classes don't actually use those methods to maintain the retain count (implementation detail, changes per platform/release, etc..)If you are going to teach retain/release, you should be treating the retain count as a delta and focus entirely on "If you increase the RC, you must decrease it".