我想构建应用程序来培训人们的内存使用情况(iOS)

时间:2011-10-11 14:16:39

标签: ios memory-management retain nsautoreleasepool

我们有很多员工对iOS编程和内存管理一般都比较新。我想构建一个带有几个标签的应用程序,显示保留计数和一些按钮来增加和减少这些保留计数。

有没有人知道那些已经有用的东西或者有任何关于设置它的建议所以它会得到我的观点?我有一个工作版本,但它似乎没有像我认为的那样工作。

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];
}

当它运行时,看起来很好,但每当我尝试按下保留按钮时崩溃。如果有人有任何建议如何清理这一点,我会很感激。理想情况下,我希望他们在保留计数达到零并且应用程序崩溃时按下访问按钮,但只要保留计数为1或更高,访问按钮就应该工作。感谢。

2 个答案:

答案 0 :(得分:4)

对象的retainCount是一件棘手的事。

如果您继续沿着这条路走下去,您应该了解以下细节:

  • retainCount永远不会返回0
  • 消息传递悬挂指针不能保证崩溃
  • 由于实施细节而导致通过任何系统API传递对象后,无法知道保留计数
  • 由于实现细节,任何系统类的任何子类都可能具有未知的保留计数
  • 保留计数从不反映对象是否已自动释放
  • autoreleases实际上是特定于线程的,而保留计数是线程全局的
  • 有些类在某些时候用单例实现(NSString,NSNumber的某些值)
  • 实施细节从平台变为平台,发布到发布
  • 尝试调动retain / release / autorelease将无效,因为某些类实际上并未使用这些方法来维护保留计数(实现细节,每个平台的更改/释放等。)

如果您要教导保留/释放,您应该将保留计数视为三角形,并完全关注“如果您增加RC,则必须减少它”。

答案 1 :(得分:3)

众所周知,

retainCount不可靠,它返回的值可能非常奇怪。检查this post