iPhone NSMutableArray 和 NSKeyedUnarchiver unarchiveObjectWithFile 发布奇怪现象
我归档了一个实现 . 一旦我将其从文件加载到保留属性 @property(非原子,保留)NSMutableArray *伙伴; 对象的释放计数为 2(正确,它是 1 个自动释放 + 1 个属性保留),但随后没有人释放它,保留计数变为 1,所以当我释放它时,我得到 -[__NSArrayM keepCount]:发送到已释放实例的消息 (我认为因为 1 个保留计数是自动释放)
这是完整的代码:
BuddieListViewController.h
#import <UIKit/UIKit.h>
#import "Buddie.h"
@interface BuddieListViewController : UITableViewController {
IBOutlet NSMutableArray *buddies;
[...]
}
[...]
@property (nonatomic, retain) NSMutableArray *buddies;
[...]
@end
BuddieListViewController.m
#import "BuddieListViewController.h"
#import "Buddie.h"
#import "PreviewViewController.h"
@implementation BuddieListViewController
@synthesize buddies;
[...]
- (id)initWithStyle:(UITableViewStyle)style
{
self = [super initWithStyle:style];
if (self) {
[self loadFromDisk];
}
return self;
}
- (void)loadFromDisk {
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsPath = [paths objectAtIndex:0];
NSString *appFile = [documentsPath stringByAppendingPathComponent:@"BuddieArchive.ark"];
NSFileManager *fileManager = [NSFileManager defaultManager];
if ([fileManager fileExistsAtPath:appFile]) {
self.buddies = [NSKeyedUnarchiver unarchiveObjectWithFile:appFile];
NSLog(@"1- buddies retain count %d (should be 2, 1 + 1autorelease)", [buddies retainCount]);
} else {
self.buddies = [NSMutableArray arrayWithCapacity:1];
}
}
[...]
- (IBAction)cancelledBuddie:(NSNotification *)notification
{
[editingBuddie release];
NSLog(@"2- buddies retain count %d (should be 2, 1 + 1autorelease)", [buddies retainCount]);
[buddies release];
[self loadFromDisk];
[self.tableView reloadData];
}
有人知道为什么会发生这种情况吗?
I archive an array (NSMutableArray) of custom objects that implement the .
Once i load it froma file to a retaining property
@property (nonatomic, retain) NSMutableArray *buddies;
the release count of the object is 2 (correct, it's 1of autorelease + 1 of retain of the property) but then noone releases it and the retain count becames 1, so when i release it i get
-[__NSArrayM retainCount]: message sent to deallocated instance
(i think because the 1 retain count is the autorelease)
Here's the full code:
BuddieListViewController.h
#import <UIKit/UIKit.h>
#import "Buddie.h"
@interface BuddieListViewController : UITableViewController {
IBOutlet NSMutableArray *buddies;
[...]
}
[...]
@property (nonatomic, retain) NSMutableArray *buddies;
[...]
@end
BuddieListViewController.m
#import "BuddieListViewController.h"
#import "Buddie.h"
#import "PreviewViewController.h"
@implementation BuddieListViewController
@synthesize buddies;
[...]
- (id)initWithStyle:(UITableViewStyle)style
{
self = [super initWithStyle:style];
if (self) {
[self loadFromDisk];
}
return self;
}
- (void)loadFromDisk {
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsPath = [paths objectAtIndex:0];
NSString *appFile = [documentsPath stringByAppendingPathComponent:@"BuddieArchive.ark"];
NSFileManager *fileManager = [NSFileManager defaultManager];
if ([fileManager fileExistsAtPath:appFile]) {
self.buddies = [NSKeyedUnarchiver unarchiveObjectWithFile:appFile];
NSLog(@"1- buddies retain count %d (should be 2, 1 + 1autorelease)", [buddies retainCount]);
} else {
self.buddies = [NSMutableArray arrayWithCapacity:1];
}
}
[...]
- (IBAction)cancelledBuddie:(NSNotification *)notification
{
[editingBuddie release];
NSLog(@"2- buddies retain count %d (should be 2, 1 + 1autorelease)", [buddies retainCount]);
[buddies release];
[self loadFromDisk];
[self.tableView reloadData];
}
Has anyone some idea of why this happens?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
我不能说比这更好的了:
不要依赖它做任何事。使用 Instruments 中的 Leaks 工具来确定是否泄漏对象。
如果你崩溃了,很可能你遇到了僵尸。请观看此视频了解如何使用 Instruments 查找僵尸。
I can't say it better than this:
Don't rely on it for anything. Use the Leaks tool in Instruments to determine if you're leaking objects.
If you're crashing, it's most likely that you have a zombie. See this video to find out how to use Instruments to find zombies.
如果需要使数组无效,请使用属性访问器将其设置为 nil:
合成的实现会处理内存管理问题。尽可能避免将
-retain/-release
消息直接发送到实例变量,而是让属性访问器为您处理事情。它会为你省去很多麻烦。If you need to nullify the array, use the property accessor to set it to
nil
:The synthesized implementation takes care of the memory management issues. Try to avoid sending
-retain/-release
messages directly to instance variables wherever possible and instead allow the property accessors to take care of things for you. It'll save you a lot of trouble.与其释放好友,不如在 loadFromDisk 开始时执行 [self.buddies removeAllObjects] 。
Rather than releasing buddies why not just do a [self.buddies removeAllObjects] at the beginning of loadFromDisk.