Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/106.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 有趣的内存错误-NSMutableArray被一致替换_Ios_Ipad_Nsmutablearray - Fatal编程技术网

Ios 有趣的内存错误-NSMutableArray被一致替换

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); }

在我的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);
}
请注意,打印点会导致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