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