2012-02-14 24 views
0

在我的iPad應用程序,我有以下功能:有趣的內存錯誤 - NSMutableArray中被替換一貫

+ (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座標用空格隔開。

每次對象點擊屏幕時,繪製一個點,並調用此方法,該方法添加一個點。請注意0​​定義爲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" 
) 

如何看整個陣列被替換爲傳入的元素?爲什麼是這樣?不,該函數在代碼中沒有被調用。它只被調用一次,每次用戶點擊屏幕在該位置繪製一個點)。

請注意,程序中的其他位置未使用這些點。只有這個功能

這裏是點的實現:

#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 
+0

你可以顯示其他地方的點正在使用? – 2012-02-14 05:13:32

+0

從字面上看沒有其他地方。 – CodeGuy 2012-02-14 05:14:08

+0

點類是什麼樣的?它們是否共享x和y的靜態變量? – 2012-02-14 05:15:21

回答

1

移動的

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

@implementation@interface

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

你聲明他們的方式使他們實際上是「全局變量」,所以所有的Dot實例將共享相同的值。將它們放在@interface中使其成爲「實例變量」,因此每個Dot可以具有不同的值。


老答案

注意

[dots addObject:d]; 

只是增加點d參考。如果您稍後在原地修改點,例如

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

然後數組中的那個也會看到相同的變化。

您需要添加副本,例如

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

我以後再也不會修改它。我添加了複製代碼,但仍然出現相同的錯誤。 – CodeGuy 2012-02-14 05:10:17

+0

@CodeGuy:請'NSLog(@「%p」,dot)'。 – kennytm 2012-02-14 05:12:13

+0

我補充說,我得到打印輸出像0x126370,0x333630等,他們是獨一無二的。 – CodeGuy 2012-02-14 05:13:47

0

您的點類需要修改,以便tapPosition不是靜態變量。

.H

@interface Dot : NSObject{ 
    @public 
    CGPoint tapPosition; 
} 
@property (nonatomic, assign) CGPoint tapPosition; 
@end 

。m

@implementation Dot 
@synthesize tapPosition; 
//... 
@end 
+0

看到更新的問題。錯誤:( – CodeGuy 2012-02-14 05:26:54