iPhone NSMutableArray 和 NSKeyedUnarchiver unarchiveObjectWithFile 发布奇怪现象

发布于 2024-09-26 13:02:36 字数 1837 浏览 8 评论 0原文

我归档了一个实现 . 一旦我将其从文件加载到保留属性 @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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

请爱~陌生人 2024-10-03 13:02:36

我不能说比这更好的了:

retainCount 返回的数字为
没用。

不要依赖它做任何事。使用 Instruments 中的 Leaks 工具来确定是否泄漏对象。


如果你崩溃了,很可能你遇到了僵尸。请观看此视频了解如何使用 Instruments 查找僵尸。

I can't say it better than this:

The number returned by retainCount is
useless.

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.

美人骨 2024-10-03 13:02:36

如果需要使数组无效,请使用属性访问器将其设置为 nil:

self.buddies = nil;

合成的实现会处理内存管理问题。尽可能避免将 -retain/-release 消息直接发送到实例变量,而是让属性访问器为您处理事情。它会为你省去很多麻烦。

If you need to nullify the array, use the property accessor to set it to nil:

self.buddies = 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.

猫卆 2024-10-03 13:02:36

与其释放好友,不如在 loadFromDisk 开始时执行 [self.buddies removeAllObjects] 。

Rather than releasing buddies why not just do a [self.buddies removeAllObjects] at the beginning of loadFromDisk.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文