ARC弱ivar在返回之前发布 - 在构建发布时,而不是调试 [英] ARC weak ivar released before being returned - when building for release, not debug

查看:100
本文介绍了ARC弱ivar在返回之前发布 - 在构建发布时,而不是调试的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个懒惰地创建对象并将其存储为弱属性的类。其他类可能会请求此对象,但显然必须对其进行强引用以防止对象被释放:

I have a class that creates an object lazily and stores it as a weak property. Other classes may request this object, but must obviously keep a strong reference to it to keep the object from being deallocated:

// .h
@interface ObjectManager
@property(nonatomic, weak, readonly) NSObject *theObject;
@end

// .m
@interface ObjectManager ()
@property(nonatomic, weak, readwrite) NSObject *theObject;
@end

@implementation ObjectManager
- (NSObject *)theObject
{
    if (!_theObject) {
        _theObject = [[NSObject alloc] init];
        // Perform further setup of _theObject...
    }
    return _theObject;
}
@end

当方案是Xcode设置为build for调试,工作正常 - 对象可以调用 objectManagerInstance.theObject 并返回 theObject

When the scheme is Xcode is set to build for Debug, things work just fine - an object can call objectManagerInstance.theObject and get back theObject.

当方案设置为Release版本时, theObject 返回 nil

When the scheme is set to build for Release, theObject returns nil:

// Build for Debug:
NSObject *object = objectManagerInstance.theObject;
// object is now pointing to theObject.

// Build for Release:
NSObject *object = objectManagerInstance.theObject;
// object is now `nil`.

我的猜测是编译器通过看到 _theObject <来优化我的代码/ code>未在accessor方法本身中进一步使用,因此在返回之前将弱变量设置为 nil 。看来我必须在实际返回变量之前创建一个强引用,我只能想用块来做,但是会很乱,我宁愿避免它!

My guess is that the compiler is optimising my code by seeing that _theObject is not used further in the accessor method itself, so the weak variable is being set to nil before returning. It seems that I would have to create a strong reference before actually returning the variable, which I can only think to do using a block, but would be messy and I'd rather avoid it!

我可以使用返回类型的某种关键字来阻止ivar这么快被禁止吗?

Is there some kind of keyword I can use with the return type to stop the ivar from being nilled so soon?

推荐答案

最有可能的是,DEBUG构建会导致对象在自动释放池中停留足够长的时间以使其工作,而RELEASE构建会使优化器进行更多的控制流分析,从而消除自动释放聊天。

Most likely, DEBUG builds cause the object to sit in the autorelease pool long enough to cause it to "work" whereas a RELEASE build causes the optimizer to do a bit more control flow analysis which subsequently eliminates the autorelease chatter.

坦率地说,编译器没有在发布版本中发出警告说代码永远无法工作是一个错误(请提交它,因为你有一个很好的,简洁的,示例)!

Frankly, that the compiler isn't spewing a warning in the release build saying that the code can never work is a bug (please file it as you have a great, concise, example)!

您需要在对象的某处维护一个强引用,直到任何需要强引用的人都有机会获取参考。

You'll need to maintain a strong reference somewhere to the object until whatever needs a strong reference has an opportunity to take a reference.

我是想知道这样的事情是否可行:

I'm wondering if something like this might work:

- (NSObject *)theObject
{
    NSObject *strongObject;
    if (!_theObject) {
        strongObject = [[NSObject alloc] init];
        _theObject = strongObject;
        // Perform further setup of _theObject...
    } else {
        strongObject = _theObject;
    }
    return strongObject;
}

I.e。上面的内容更类似于返回自动释放对象的工厂方法,而在内部维护弱引用。但是优化器可能太聪明了一半也打破了上述。

I.e. the above would be more akin to a factory method that returns an autoreleased object while also maintaining a weak reference internally. But the optimizer might be too clever by half and break the above, too.

这篇关于ARC弱ivar在返回之前发布 - 在构建发布时,而不是调试的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆