isa 变量重置为 nil 的任何可能原因?

发布于 2024-12-11 05:01:38 字数 1305 浏览 0 评论 0原文

我的iPhone应用程序运行一段时间后不断收到BAD_EXC_ACCESS错误,经过痛苦的调试,我发现我的一个静态变量(确切地说是NSPredicate)已损坏:它仍然指向原始地址,但它的isa变量被重置为0!

这完全让我困惑,为什么 isa 变量被重置为 0?!有什么想法吗?

谢谢!

更新:发布代码。代码实际上来自 erica 的 ABContactHelper 我对其进行了一些更改以使用谓词模板来使查询更高效,所以我添加了这个功能:

+ (NSPredicate*) predicateforMatchingName:(NSString*) name {
        //templateForMatchingName is a static variable I declare elsewhere
        //static NSPredicate * templateForMatchingName =nil;
    if (templateForMatchingName == nil) {
        templateForMatchingName = [NSPredicate predicateWithFormat:@"firstname contains[cd] $NAME1 OR lastname contains[cd] $NAME2 OR nickname contains[cd] $NAME3 OR middlename contains[cd] $NAME4"];
    }

    NSDictionary *sub = [NSDictionary dictionaryWithObjectsAndKeys:
                         name,@"NAME1",
                         name,@"NAME2",
                         name,@"NAME3",
                         name,@"NAME4",
                         nil];

    NSPredicate *pred = [templateForMatchingName predicateWithSubstitutionVariables:sub];
    return pred;
} 

我认为这段代码是完美的“正常”,templateForMatchingName 创建后不可能更改。但后来我发现它的isa变量被重置了。它不一定设置为零。这次我发现它被重置为不同的值。而且奇怪的是它仍然指向原来的区域。

有什么想法吗?

My iPhone app keeps receiving BAD_EXC_ACCESS error after running for a while, after painful debugging I find that one of my static variables (NSPredicate to be exact) was corrupted: it still pointed to the original address, but its isa variable was reset to 0!

This totally beats me, how come the isa variable was reset to 0 ?! Any idea ?

Thanks!

Update: post the code. The code is actually from erica's ABContactHelper I changed it a little bit to use Predicate Templates to make query more efficient, so I added this function:

+ (NSPredicate*) predicateforMatchingName:(NSString*) name {
        //templateForMatchingName is a static variable I declare elsewhere
        //static NSPredicate * templateForMatchingName =nil;
    if (templateForMatchingName == nil) {
        templateForMatchingName = [NSPredicate predicateWithFormat:@"firstname contains[cd] $NAME1 OR lastname contains[cd] $NAME2 OR nickname contains[cd] $NAME3 OR middlename contains[cd] $NAME4"];
    }

    NSDictionary *sub = [NSDictionary dictionaryWithObjectsAndKeys:
                         name,@"NAME1",
                         name,@"NAME2",
                         name,@"NAME3",
                         name,@"NAME4",
                         nil];

    NSPredicate *pred = [templateForMatchingName predicateWithSubstitutionVariables:sub];
    return pred;
} 

I have thought this code is perfect "normal", templateForMatchingName is impossible to be changed after it was created. But then I find its isa variable was reset. It is not necessarily set to nil. This time I find it was reset to different value. And the weird thing is that it still pointed to the original area.

Any idea?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

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

发布评论

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

评论(3

你的笑 2024-12-18 05:01:38

您正在调用一个返回自动释放对象的类方法;尝试在实例化期间添加嵌套保留,或者仅使用 alloc&init。

是的,指针将指向原始地址,这就是它抛出该异常的原因。如果指针设置为 nil,由于 if 语句,它会再次实例化您的对象。

You are calling a class method that returns an autoreleased object; try adding a nested retain during instantiation, or just use alloc&init.

And yes, the pointer would point to the original address, that's why it throws that exception. If the pointer was set to nil it would have instantiated your object again due to the if statement.

浅浅淡淡 2024-12-18 05:01:38

可能该对象已被释放并且其内存在某个时刻被重用。用 Zombies 仪器试试看。现在您已经发布了代码,我发现情况确实如此。 predicateWithFormat: 方法返回一个不属于您的实例,该实例可能会在当前自动释放池的生命周期结束后被释放。如果你想保留它,你需要保留它(如果你重新分配变量,则释放该对象)。

Probably the object was released and its memory reused at some point. Try it with the Zombies instrument and see. And now that you've posted your code, I see this is indeed the case. The predicateWithFormat: method returns an instance you don't own, which is liable to be released after the current autorelease pool's life is up. You need to retain it if you want to keep it around (and release the object if you reassign the variable).

清风挽心 2024-12-18 05:01:38

谢谢家伙!正是这个原因;在我保留我的对象后,问题就解决了。我想我对静态变量及其指向的底层数据感到困惑。

顺便说一句,对于其他可能对该问题感兴趣的人,您也可以参考此,为什么要保留静态变量?

这里学到的另一个教训是,每当isa变量被重置时,就意味着对象进程已经回收了内存。

Thanks guy! That's exactly the reason; after I retain my object the problem was solved. I think I confused with the static variable and the underlying data it pointers to.

BTW, for others who may be interested in the problem, you can refer to this as well, Why retain a static variable?

Another lesson learned here is that whenever isa variable is reset, it means the memory that object process has been reclaimed.

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