ios 想要ARC的自动释放寿命

j7dteeu8  于 2023-05-30  发布在  iOS
关注(0)|答案(3)|浏览(121)

在iOS上过渡到ARC。
我有一个自动释放的NSString,我用它来生成UTF-8表示,并依赖于池的生存期来保持UTF-8指针的活动:

char *GetStringBuffer(something)
{
    NSString *ns = [NSString stringWithSomething:something];
    return [ns UTF8String];
}

something的性质在这里并不重要。
ARC前规则确保返回的数据指针在当前自动释放池的生存期内保持有效。关键的是,我不随身携带NSString指针。
现在,在ARC下,函数返回时字符串不会被释放吗?我不认为ARC会将一个char *的NSString内部结构视为强引用,尤其是看到它从未被显式释放。
这里最好的ARC成语是什么?

lo8azlld

lo8azlld1#

如果要保证UTF8String的返回值在当前自动释放池耗尽之前有效,有两个选项:
1.在compiled with ARC disabled文件中定义GetStringBuffer。如果stringWithSomething:遵循约定,则必须将自动释放的NSString返回给非ARC调用方。如果没有(例如它的作用类似于-[NSArray objectAtIndex:]),您可以显式地retainautorelease它。
1.使用免费桥接和CFAutorelease

char *GetStringBuffer(something) {
    NSString *ns = [NSString stringWithSomething:something];
    CFAutorelease(CFBridgingRetain(ns));
    return [ns UTF8String];
}
zu0ti5jz

zu0ti5jz2#

我认为正确的方法是使用__autoreleasing
https://releases.llvm.org/11.1.0/tools/clang/docs/AutomaticReferenceCounting.html#storage-duration-of-autoreleasing-objects
例如

char *GetStringBuffer(something) NS_RETURNS_INNER_POINTER {
    __autoreleasing NSString * ns = [NSString stringWithSomething:something];

    return [ns UTF8String];
}
to94eoyn

to94eoyn3#

(我不能删除这个,因为它被接受了,但这个答案是不正确的。请参阅Rob Mayoff的答案,以及对该答案的评论以获得解释。不保证此指针在返回语句之后有效。)

重写我的整个答案。不得不挖啊挖,但我相信这是令人惊讶的安全今天(由于改进弧,因为我有我的崩溃;我知道这样的东西在我的脑海里滚动)。原因如下:

@property (readonly) __strong const char *UTF8String NS_RETURNS_INNER_POINTER;  // Convenience to return null-terminated UTF8 representation

UTF8String标记为NS_RETURNS_INNER_POINTER,实际上是objc_returns_inner_pointer。调用该方法:
对象的生存期将至少延长到以下时间中的最早时间:

  • 在调用函数中最后一次使用返回的指针或从它派生的任何指针,或
  • 自动释放池恢复到先前状态。

你就是这么想的。

相关问题