Ios 如何在类中将uu自动释放地址保持为强属性?

Ios 如何在类中将uu自动释放地址保持为强属性?,ios,iphone,objective-c,c,pointers,Ios,Iphone,Objective C,C,Pointers,如何使变量的地址成为NSObject中的强属性?我有一个名为SCPFMessageThreadQuery的类,它是通过传递SCPFMessageThread变量的地址来初始化的 @interface SCPFMessageThreadQuery () // This declaration seems correct. @property (nonatomic) SCPFMessageThread *__strong *thread; - (id)initWithRootMessage:(S

如何使变量的地址成为
NSObject
中的强属性?我有一个名为
SCPFMessageThreadQuery
的类,它是通过传递
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*\uuuu autoreleasing*”分配给“SCPFMessageThread*\uuuu strong*”会更改指针的保留/释放属性

我计划从视图控制器以以下方式使用此类:

SCPFMessageThread *thread = self.thread; // self.thread can be nil
SCPFMessageThreadQuery *query = [[SCPFMessageThreadQuery alloc]
    initWithRootMessage:self.rootMessage threadAddress:&thread];
我真的需要把地址传过来。我将多次调用我们的API来完成应用程序代码中单个对象(
SCPFMessageThread
)的信息。请不要问我为什么API不自己进行连接。

要显示问题:

@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()
是针对CF对象的问题,则可以使用
CFRetain()
等。)

甚至你也明确地证实了这一点:为什么你需要额外的间接成本?如果你真的,真的需要它,想想中间的一个额外的物体:

@interface NSStringRetainableReference
@property NSString *string;
@end

@implementation
@end
将此类的实例对象作为参数传递。然后有一个指向可保留对象的指针和另一个间接级别。但在这种情况下,它是从一个对象构建的。

要显示问题:

@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()
是针对CF对象的问题,则可以使用
CFRetain()
等。)

甚至你也明确地证实了这一点:为什么你需要额外的间接成本?如果你真的,真的需要它,想想中间的一个额外的物体:

@interface NSStringRetainableReference
@property NSString *string;
@end

@implementation
@end

将此类的实例对象作为参数传递。然后有一个指向可保留对象的指针和另一个间接级别。但是在这种情况下,它是从一个对象建立起来的。

除了局部变量之外,不能对任何东西使用
\uu自动删除
存储。自动释放是每个线程的行为。跨线程或跨可能弹出自动释放池的堆栈帧共享存储是不安全的

默认情况下,
SomeObject**
类型的参数是
\uu自动释放
。您可以更改您的方法声明,使其可以使用强变量。然后您可以将其直接用于strong property的ivar:

- (id)initWithRootMessage:(SCPFMessage *)root threadAddress:(SCPFMessageThread * __strong *)address

请注意,当您获取ivar或局部变量的地址时,ARC不会确保包含对象或堆栈帧的寿命与您需要的一样长。

除了局部变量之外,您不能对任何内容使用
\u autoreleasing
存储。自动释放是每个线程的行为。跨线程或跨可能弹出自动释放池的堆栈帧共享存储是不安全的

默认情况下,
SomeObject**
类型的参数是
\uu自动释放
。您可以更改您的方法声明,使其可以使用强变量。然后您可以将其直接用于strong property的ivar:

- (id)initWithRootMessage:(SCPFMessage *)root threadAddress:(SCPFMessageThread * __strong *)address

请注意,当您获取ivar或局部变量的地址时,ARC并不能确保包含的对象或堆栈帧的寿命与您需要的一样长。

“您的指针指向一个C指针,它不是一个可保留的对象。”请记住这一点。“你的指针指向一个C指针,它不是一个可保留的对象。”记住这一点。+1另一个“解决方案”表明没有简单的解决方案,但一个突破限制的需求弧可以处理。+1另一个“解决方案”表明没有简单的解决方案,但一个突破限制的需求弧可以处理。