Ios 有趣的内存错误-NSMutableArray被一致替换
在我的iPad应用程序中,我有以下功能:Ios 有趣的内存错误-NSMutableArray被一致替换,ios,ipad,nsmutablearray,Ios,Ipad,Nsmutablearray,在我的iPad应用程序中,我有以下功能: + (void)addDot:(Dot *)d { if(dots == nil) dots = [[NSMutableArray alloc] init]; NSLog(@"before adding, dots = %@",dots); NSLog(@"adding dot %@",d); [dots addObject:d]; NSLog(@"dots is now %@",dots); }
+ (void)addDot:(Dot *)d {
if(dots == nil)
dots = [[NSMutableArray alloc] init];
NSLog(@"before adding, dots = %@",dots);
NSLog(@"adding dot %@",d);
[dots addObject:d];
NSLog(@"dots is now %@",dots);
}
请注意,打印点会导致x、y坐标被空格分隔
每次主体轻触屏幕时,都会绘制一个点,并调用此方法,添加一个点。请注意,dots
定义为该函数所在类顶部的静态NSMutableArray*dots
。有些奇怪的事情正在发生。数组的每个元素都被替换。点击屏幕后,在最开始处查看NSLog
中的输出,制作两个点:
before adding, dots = (
)
2012-02-13 23:58:48.159 MoreMost[520:707] adding dot 418.000000 548.000000
2012-02-13 23:58:48.161 MoreMost[520:707] dots is now (
"418.000000 548.000000"
)
2012-02-13 23:58:48.748 MoreMost[520:707] before adding, dots = (
"635.000000 410.000000"
)
2012-02-13 23:58:48.749 MoreMost[520:707] adding dot 635.000000 410.000000
2012-02-13 23:58:48.750 MoreMost[520:707] dots is now (
"635.000000 410.000000",
"635.000000 410.000000"
)
查看如何用传入元素替换整个阵列?为什么会这样?不,在代码中的任何其他地方都不会调用该函数。每次用户点击屏幕在该位置画一个点时,只调用一次)
请注意,程序中的其他任何地方都没有使用这些点。仅此功能
以下是Dot的实现:
#import "Dot.h"
@implementation Dot
@synthesize tapPosition;
CGRect frame;
UIColor *dotColor;
float radius = 20;
- (id)initWithTapPosition:(CGPoint)pt color:(UIColor *)col {
if(self = [super init]) {
tapPosition = pt;
float topLeftX = pt.x - radius;
float topLeftY = pt.y - radius;
if(topLeftX + (radius*2) >= 1024)
return nil;
if(topLeftY + (radius*2) >= 728)
return nil;
if(topLeftY <= 0 || topLeftX <= 0)
return nil;
frame = CGRectMake(topLeftX, topLeftY, radius*2, radius*2);
dotColor = col;
}
return self;
}
- (id)copyWithZone:(NSZone *)zone
{
Dot *dot = [[[self class] allocWithZone:zone] initWithTapPosition:tapPosition color:dotColor];
return dot;
}
- (CGRect)getFrame {
return frame;
}
- (UIColor *)getColor {
return dotColor;
}
- (NSString *)description {
return [NSString stringWithFormat:@"%f %f",frame.origin.x,frame.origin.y];
}
@end
#导入“Dot.h”
@实现点
@合成tapPosition;
CGRect帧;
UIColor*dotColor;
浮动半径=20;
-(id)initWithTapPosition:(CGPoint)pt color:(UIColor*)col{
if(self=[super init]){
t位置=pt;
浮点数topLeftX=pt.x-半径;
float topLeftY=pt.y-半径;
如果(topLeftX+(半径*2)>=1024)
返回零;
if(topLeftY+(半径*2)>=728)
返回零;
如果(左上角移动
CGRect frame;
UIColor *dotColor;
CGPoint tapPosition;
float radius = 20;
从@实现
到@接口
:
@interface Dot : NSObject
{
CGRect frame;
// etc.
}
...
@end
您声明它们的方式实际上使它们成为“全局变量”,因此所有点实例将共享相同的值。将它们放在@界面中
将它们改为“实例变量”,以便每个点可以有不同的值
旧答案
注意
[dots addObject:d];
仅添加点d
的参考。如果以后在适当位置修改点,例如:
d.x = 123;
d.y = 456;
那么数组中的一个也会看到相同的变化
您需要添加一份副本,例如
[dots addObject:[d copy]];
// note: you need to implement -copyWithZone: with the <NSCopying> protocol
[dots addObject:[d copy]];
//注意:您需要使用协议实现-copyWithZone:
需要修改dots类,使tapPosition不是静态变量
h
m
我以后再也没有修改过它。我添加了复制代码,但仍然得到相同的错误。@CodeGuy:请NSLog(@“%p”,dot)
。我添加了它,我得到了0x126370、0x333630等打印输出。它们是独一无二的。@CodeGuy:我明白了。你能展示一下Dot类的@接口和/或@实现吗?因为你使用的是ARC,我相信这个答案比我自己的答案更正确。你能展示一下dots正在使用的其他地方吗?不现在我们还需要。dot类是什么样子的?它们是否为x和y共享一个静态变量?如果dots
为nil,则添加一个NSLog或断点会发生什么情况?您将在哪里释放dots
?您也可以在那里放置一个断点。如果在两次点击之间释放dots
,您将为其创建一个新的dots
每个传入元素。但我在一种模式下使用Xcode,无法执行“保留”或“释放”之类的操作。它为我管理内存。这是一个项目创建时的设置。如果我在if循环中放入print语句,它只打印“dots”为零的一次。
[dots addObject:[d copy]];
// note: you need to implement -copyWithZone: with the <NSCopying> protocol
@interface Dot : NSObject{
@public
CGPoint tapPosition;
}
@property (nonatomic, assign) CGPoint tapPosition;
@end
@implementation Dot
@synthesize tapPosition;
//...
@end