Xcode 在Cocoa中一般分配内存的安全方法,该内存将自动释放

Xcode 在Cocoa中一般分配内存的安全方法,该内存将自动释放,xcode,cocoa,memory,memory-management,automatic-ref-counting,Xcode,Cocoa,Memory,Memory Management,Automatic Ref Counting,在我的可可项目中,我有很多地方使用malloc/free。然而,几个月前,我决定重构以利用ARC,为了实现这一点,我尝试替换malloc,它将返回指向将自动清理的内容的指针 我使用了这个函数(省略了错误检查和其他日志记录) 这在一段时间内运行良好,但最近出现了一个随机内存覆盖问题。我找到了这个函数的原因,似乎发生的是NSMutableData实例正在被释放,尽管我保留了一个指向它的mutableBytes的指针 我猜这是因为对对象的唯一直接引用是本地的,并且正在消失,而可变字节指向对象内部,所以

在我的可可项目中,我有很多地方使用malloc/free。然而,几个月前,我决定重构以利用ARC,为了实现这一点,我尝试替换malloc,它将返回指向将自动清理的内容的指针

我使用了这个函数(省略了错误检查和其他日志记录)

这在一段时间内运行良好,但最近出现了一个随机内存覆盖问题。我找到了这个函数的原因,似乎发生的是NSMutableData实例正在被释放,尽管我保留了一个指向它的mutableBytes的指针

我猜这是因为对对象的唯一直接引用是本地的,并且正在消失,而可变字节指向对象内部,所以弧不够聪明,无法处理这种引用计数


是否有任何方法可以重构此代码以在使用mutableBytes指针时保留mutableData对象(即有人引用它)?我知道一个选择是只返回NSMutableData本身,但这需要一些繁重的重构,而且看起来非常混乱。

我想你回答了你自己的问题。如果您想使用
NSData
来管理通用内存分配,则需要保留对
NSData
对象的引用,直到使用完它所拥有的内存,此时您将取消对相关NSData对象的引用。与手动释放malloced内存相比,这似乎没有任何优势。就我个人而言,我将继续显式地使用malloc()/free(),而不是试图以某种方式扭曲我的代码,使之管理malloced内存


要么这样,要么我就编写代码,这样它就不必首先使用malloc/free。我要说的是,典型的“纯”Cocoa项目没有太多(如果有的话)显式malloc()调用,除非有充分的理由,否则我会有点怀疑这样做的代码。你为什么要首先使用malloc()?

我想你回答了你自己的问题。如果您想使用
NSData
来管理通用内存分配,则需要保留对
NSData
对象的引用,直到使用完它所拥有的内存,此时您将取消对相关NSData对象的引用。与手动释放malloced内存相比,这似乎没有任何优势。就我个人而言,我将继续显式地使用malloc()/free(),而不是试图以某种方式扭曲我的代码,使之管理malloced内存


要么这样,要么我就编写代码,这样它就不必首先使用malloc/free。我要说的是,典型的“纯”Cocoa项目没有太多(如果有的话)显式malloc()调用,除非有充分的理由,否则我会有点怀疑这样做的代码。为什么首先要使用malloc()。

在10.7 SDK中,
-[NSMutableData mutableBytes]
NS\u RETURNS\u internal\u POINTER
属性修饰。这向编译器发出信号,表示该方法返回一个指针,其有效性取决于仍然存在的接收器。ARC对此的具体作用有待改变,但目前它保留并自动释放接收器(取决于优化的冗余操作)

因此,指针在当前自动释放池的生存期内有效。这类似于
-[NSString UTF8String]
(其装饰方式相同)

只要存在对字节指针的引用,ARC就无法保持可变数据对象的活动状态。ARC不是垃圾收集器。它不会监视所有指针的所有用法。它在当地运作。它检查一个给定的函数、方法或块,并根据命名约定发出代码行为的保留和释放。(请记住,ARC可与未使用ARC支持编译的代码进行互操作。)

由于
void*
不是对象指针,无法保留或释放,因此ARC无法对其执行任何操作。因此,在调用
-MallocWithAutoCleanup:
方法的代码中,ARC看不到它可以管理的任何东西。它不发出任何特殊的内存管理代码。(此时它会发出什么?)在编译调用程序时,编译器可能对方法实现或其中的可变数据对象一无所知


换一种方式考虑:如果您仍然在手动编写引用计数代码,您会在方法的调用者中做什么来保持指针有效?在大多数情况下(忽略
\u弱
引用),ARC所做的只是自动执行您手动执行的操作。一旦你认为在那种情况下你就没有选择,你就会意识到,在10.7 SDK中,ARC.

< P>,<代码> -[NSMutabeDebug MutabelByth] < /C> >用<代码> NSU-ReursSnInLyPosith属性进行修饰。这向编译器发出信号,表示该方法返回一个指针,其有效性取决于仍然存在的接收器。ARC对此的具体作用有待改变,但目前它保留并自动释放接收器(取决于优化的冗余操作)

因此,指针在当前自动释放池的生存期内有效。这类似于
-[NSString UTF8String]
(其装饰方式相同)

只要存在对字节指针的引用,ARC就无法保持可变数据对象的活动状态。ARC不是垃圾收集器。它不会监视所有指针的所有用法。它在当地运作。它检查一个给定的函数、方法或块,并根据命名约定发出代码行为的保留和释放。(请记住,ARC可以与未被修改的代码进行互操作
+ (void *) MallocWithAutoCleanup: (size_t) size 
{
    NSMutableData * mutableData = [[NSMutableData alloc] initWithLength:size];
    void * data = [mutableData mutableBytes];
    return data;
}