gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-11-29 04:48:23 26 4
gpt4 key购买 nike

在我的 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 被定义为该函数所在类顶部的 static NSMutableArray *dots。发生了一些奇怪的事情。数组的每个元素都被替换。点击屏幕后,查看 NSLog 的输出,形成 2 个点:

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

和标题:

    #import <Foundation/Foundation.h>

@interface Dot : NSObject {
@public
CGPoint tapPosition;
}

@property (nonatomic, assign) CGPoint tapPosition;

- (CGRect)getFrame;
- (id)initWithTapPosition:(CGPoint)pt color:(UIColor *)col;

- (UIColor *)getColor;
@end

最佳答案

移动

CGRect frame;
UIColor *dotColor;
CGPoint tapPosition;
float radius = 20;

@implementation@interface:

@interface Dot : NSObject
{
CGRect frame;
// etc.
}
...
@end

声明它们的方式使它们实际上成为“全局变量”,因此所有 Dot 实例将共享相同的值。将它们放入 @interface 中,使它们成为“实例变量”,这样每个点都可以有不同的值。

<小时/>

旧答案

请注意

[dots addObject:d];

仅添加点d引用。如果您稍后就地修改点,例如

d.x = 123;
d.y = 456;

那么数组中的那个也会看到同样的变化。

您需要添加一个副本,例如

[dots addObject:[d copy]];
// note: you need to implement -copyWithZone: with the <NSCopying> protocol

关于ios - 有趣的内存错误 - NSMutableArray 被一致替换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9271940/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com