在我的 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/