[英]How to keep an __autoreleasing address as a strong property in a class?
如何在NSObject
中將變量的地址NSObject
強屬性? 我有一個名為SCPFMessageThreadQuery
的類,它通過傳遞SCPFMessageThread
變量的地址來進行SCPFMessageThread
。
@interface SCPFMessageThreadQuery ()
// This declaration seems correct.
@property (nonatomic) SCPFMessageThread *__strong *thread;
- (id)initWithRootMessage:(SCPFMessage *)root threadAddress:(SCPFMessageThread **)address;
@end
@implementation SCPFMessageThreadQuery
// Xcode somehow makes the ownership type __autoreleasing here during autocompletion.
- (id)initWithRootMessage:(SCPFMessage *)root threadAddress:(SCPFMessageThread *__autoreleasing *)address
{
if (self = [super init]) {
_root = root;
// ERROR HERE. Xcode complains about changing the ownership of address.
_thread = address;
}
return self;
}
@end
我得到的錯誤是這樣的:
將'SCPFMessageThread * __ autoreleasing *'分配給'SCPFMessageThread * __ strong *'更改指針的保留/釋放屬性
我計划從我的視圖控制器以下列方式使用此類:
SCPFMessageThread *thread = self.thread; // self.thread can be nil
SCPFMessageThreadQuery *query = [[SCPFMessageThreadQuery alloc]
initWithRootMessage:self.rootMessage threadAddress:&thread];
我真的需要在這里傳遞地址。 我將對API進行多次調用,以便在應用程序代碼中完成單個對象( SCPFMessageThread
)的信息。 請不要問我為什么API不會執行JOIN本身。
您不能將__autoreleasing
存儲用於除局部變量之外的任何內容。 Autorelease是一種每線程行為。 跨線程或跨可能彈出自動釋放池的堆棧幀共享__autoreleasing
存儲是不安全的。
默認情況下, SomeObject **
類型的參數是__autoreleasing
。 您可以更改方法聲明,以便使用強變量。 然后你可以直接用你強大的財產的ivar:
- (id)initWithRootMessage:(SCPFMessage *)root threadAddress:(SCPFMessageThread * __strong *)address
請注意,當您獲取ivar或局部變量的地址時,ARC不會確保包含對象或堆棧幀只要您需要它就可以存活。
要顯示問題:
@interface AppDelegate ()
@property NSString * __strong * ivar;
@end
@implementation AppDelegate
- (void)storeIndirect:(NSString * __autoreleasing *)par
{
id xpar = *par;
_ivar = &xpar;
}
@end
通過取消引用,您可以指向可保留對象。 只有這些(而不是 “指向可保留對象的指針”)才是ARC的主題。 因此, xpar
指向的對象將被保留 - 並在方法結束時釋放。
當然,您可以將xpar
存儲到屬性中以保存它。 但這很明顯整個代碼都沒用:雙重間接將在ARC中丟失。 ARC關心指針后面的對象(如果它是可保留的對象)。 您的指針指向C指針,該指針不是可保留的對象。
我不認為有一個簡單的解決方案。 (但是你可以使用CFRetain()
等,如果你不關心或多或少的理論CFRetain()
是針對CF對象的問題。)
即使你明確地證實了這一點:為什么你需要額外的間接水平? 如果你真的真的需要它,那么考慮一下中間的額外物體:
@interface NSStringRetainableReference
@property NSString *string;
@end
@implementation
@end
將此類的實例對象作為參數傳遞。 然后你有一個指向可保留對象和另一個間接層的指針。 但在這種情況下,它是從一個對象構建的。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.