Objective c 合成副本属性未与ARC解除分配

Objective c 合成副本属性未与ARC解除分配,objective-c,ios,Objective C,Ios,在我的项目中,我正在管理几个图形对象。我正在尝试将SmartPath对象的副本添加到图形对象。这很有效。但当图形解除分配时,SmartPath不会。我在图形的dealoc中添加了一些额外的代码,以显式地设置指向SmartPath的清除指针。出于某种原因,这是可行的(保留计数为1)。我知道我可能可以复制SmartPath并将其指定给一个强参数来修复此漏洞。但我对IOS比较陌生,我想知道如何将复制参数与ARC结合使用 代码如下: 绘图。h: @interface Drawing : NSObject

在我的项目中,我正在管理几个图形对象。我正在尝试将SmartPath对象的副本添加到图形对象。这很有效。但当图形解除分配时,SmartPath不会。我在图形的dealoc中添加了一些额外的代码,以显式地设置指向SmartPath的清除指针。出于某种原因,这是可行的(保留计数为1)。我知道我可能可以复制SmartPath并将其指定给一个强参数来修复此漏洞。但我对IOS比较陌生,我想知道如何将复制参数与ARC结合使用

代码如下:

绘图。h:

@interface Drawing : NSObject{
@private
    SmartPath* rawLinePath;         //path that is build up from straight lines between input points
    SmartPath* smoothLinePath;      //smoothened version of rawLinePath
}


@property(atomic,copy)SmartPath* rawLinePath;
@property(atomic,copy)SmartPath* smoothLinePath;
绘图.m

@implementation Drawing
@synthesize rawLinePath;
@synthesize smoothLinePath;



-(id)init
{
    if (self = [super init])
    {        
        [NSThread detachNewThreadSelector:@selector(pointMonitor) 
                                 toTarget:self 
                               withObject:nil];  
    }
    return self;
}

-(void)dealloc{
    rawLinePath=nil;
}
/*
 * Init - set all variables in the correct state
 */
-(id)init
{
    if (self = [super init])
    {        
        visible=TRUE;
        color = [UIColor redColor].CGColor;
        width = SMARTPATH_LINE_WIDTH;
        path = CGPathCreateMutable();
        lock = [[NSLock alloc]init];
    }
    return self;
}

/*
 * dealloc - clean up after self 
 */
-(void)dealloc{
    CGPathRelease(path);
}

/*
 * copy method to be able to pass a SmartPath to a copy property
 */
-(id)copyWithZone:(NSZone *)zone{
    SmartPath *pathCopy = [[SmartPath allocWithZone: zone] init];
    pathCopy.visible =visible;
    pathCopy.color = color;
    pathCopy.width = width;
    return pathCopy;
}
SmartPath.m

@implementation Drawing
@synthesize rawLinePath;
@synthesize smoothLinePath;



-(id)init
{
    if (self = [super init])
    {        
        [NSThread detachNewThreadSelector:@selector(pointMonitor) 
                                 toTarget:self 
                               withObject:nil];  
    }
    return self;
}

-(void)dealloc{
    rawLinePath=nil;
}
/*
 * Init - set all variables in the correct state
 */
-(id)init
{
    if (self = [super init])
    {        
        visible=TRUE;
        color = [UIColor redColor].CGColor;
        width = SMARTPATH_LINE_WIDTH;
        path = CGPathCreateMutable();
        lock = [[NSLock alloc]init];
    }
    return self;
}

/*
 * dealloc - clean up after self 
 */
-(void)dealloc{
    CGPathRelease(path);
}

/*
 * copy method to be able to pass a SmartPath to a copy property
 */
-(id)copyWithZone:(NSZone *)zone{
    SmartPath *pathCopy = [[SmartPath allocWithZone: zone] init];
    pathCopy.visible =visible;
    pathCopy.color = color;
    pathCopy.width = width;
    return pathCopy;
}
我希望你们中的任何人都知道这个问题的答案。
向您致意

您的问题是调用
-detachNewThreadSelector:toTarget:withObject:
。这将保留
target
,即
self
,并在退出
pointMonitor
之前不会释放它。我怀疑这永远不会发生,所以您已经有效地创建了一个retain循环

您几乎不应该使用
-detachNewThreadSelector:toTarget:withObject:
。它可以创建无限数量的线程。相反,您通常应该使用调度队列、
NSTimer
NSOperation
或其他异步机制
NSThread
对象通常只适用于长寿命的生产者/消费者线程(通常使用诸如分派队列之类的较新工具处理这些线程会更好)

我不确定
pointMonitor
是做什么的,但它需要自己的线程有什么原因吗?你可以做很多很好的Cocoa开发工作,而且永远不会出错。您能在这里使用
NSTimer
吗?请注意,这些技术中的大多数在启动之前都会保留其目标(就像
NSThread
)。如果他们不这样做,你就会在他们开火时崩溃


在不知道你想做什么的情况下,我不确定该推荐哪种方法。您可能想把它作为一个新的问题放在一起。

如果不在实例变量名称的开头加下划线,那么您将得到一段代码,您永远不知道您使用的是访问器方法还是实例变量。因此,您永远无法确定是否制作了副本

如果您在其他地方这样做,则很有可能对SmartPath对象的引用被卡在某个地方。您在创建NSLock对象时做了什么?你需要做@synchronized用更少的代码做不到的事情吗

如果您使用的是较新的Xcode版本,请删除所有实例变量和@synthesis语句。只需声明属性


请原谅,从init方法中分离线程只是一种病态

我创建的线程没有问题。pointMonitor确实退出并通过圆弧释放保留的对象。我读了更多,发现ARC不再支持复制属性。不幸的是,编译器未能就此向我发出警告。我认为,在指定一方面由ARC释放,另一方面必须显式设置为nil的位置时,这会创建一个双保留。执行多个线程是为了减少阻塞UI线程的时间。我不想在UI线程中创建线程,但这不是问题所在。这实际上为我关闭了它,你所说的“复制属性不再受ARC支持”是什么意思?很抱歉,我找不到我在哪里读到的了。我想那不是真的