0

一般来说,我们有很多对 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 或更好,访问按钮就应该工作。谢谢。

4

2 回答 2

4

retainCount对象是棘手的事情。

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

  • retainCount永远不能返回 0
  • 不保证向悬空指针发送消息会崩溃
  • 由于实现细节,一旦您通过任何系统 API 传递了一个对象,就无法知道保留计数
  • 由于实现细节,任何系统类的任何子类都可能具有未知的保留计数
  • 保留计数从不反映对象是否自动释放
  • autoreleases 实际上是线程特定的,而保留计数是线程全局的
  • 某些类有时是用单例实现的(NSString,NSNumber 的某些值)
  • 实现细节因平台而异,版本因版本而异
  • 尝试 swizzle //retain不会起作用,因为某些类实际上并没有使用这些方法来维护保留计数(实现细节、每个平台/版本的更改等)releaseautorelease

如果您要教授保留/释放,则应将保留计数视为增量,并完全专注于“如果增加 RC,则必须减少它”。

于 2011-10-11T15:00:54.960 回答
3

retainCount是出了名的不可靠,它返回的值可能非常奇怪。看看这个帖子

于 2011-10-11T14:19:33.223 回答