在类接口中,我定义了一些属性
@property (strong,nonatomic) id < Protocol > initEst; // Initial estimate
然后再在类消息中输入我的意思
...
@autoreleasepool
{
something = ...; // alloc'd and init'd here ...
self.initEst = something; // retain as class variable for later
}
...
[我认为ARC可以正常工作,以后需要时self.initEst
将可用。
但不是。它不是nil
,但是调试器显示它是指向[0]
的有效指针?我怀疑自动释放池会以某种方式释放它,因此我尝试保留它,但没有任何乐趣。另外,当我以任何方式向它发送消息时,我会得到关于CFString
的非常奇怪的错误,我没有在附近使用它。
发生了什么事?
[另外,有人可以确认在autoreleasepool内进行某些工作,然后将结果保留在类变量中以供以后在autoreleasepool之外使用时没有错吗?与上面的操作几乎相同,但名称不同。
全部有关ARC自动内存管理的规则。初始化程序对如何处理返回的值有特殊的规则:它将保留并返回。参见https://clang.llvm.org/docs/AutomaticReferenceCounting.html#semantics-of-init。
一般而言,Objective-C,尤其是ARC,对于方法名称的含义有一些非常严格的规则。 initXXX
的意思是“这是一个初始化程序”。如果这不是初始化程序,请不要使用init
前缀。
您可以完全关闭ARC并自行管理内存,但是遵守约定会更容易,并且在与其他语言(例如Swift)进行交互的情况下更适合。
我已经对此进行了更多测试,并且似乎有[[3个条件可以使这个特殊问题出现。
在我的特殊情况下,ivar的Protocol
也与包含类的相同。这似乎是此问题浮出水面的一项附加要求(此处指的是我之前未提及此问题的答案)。因此,请详细说明我先前的答案。如果
initXXX
是一个ivarid
类型的Protocol
,它与包含的类的这里是我用来测试的代码示例
@interface Dog : NSObject < Animal >
@property (nonatomic,strong) id < Animal > initState;
@end
类似这样的东西会引起问题,只是因为名称以开头。更改名称,所有问题都会消失。作为参考,此生成的运行时错误为init
已取消分配时已释放的狗对象
此代码段非常抽象,但是这可能会在您需要指定一些初始条件以及很自然地将一些ivar initXxx
命名的地方咬住您,但是请注意,如果您使用Objective-C,您将没有那么奢侈或编译器会警告您这是错误的。
原始错误似乎与内存分配有关,并且使我怀疑我使用
autoreleasepool
的方式,但是现在我相当确信这与问题无关。