2010-05-19 75 views
0

我有一個Cocos2D iPhone應用程序,需要一組CGRect覆蓋在圖像上來檢測它們中的觸摸。下面的「數據」是一個保存從XML文件解析的值的類。 「delegateEntries」是一個NSMutableArray,包含多個「數據」對象,從另一個名爲「條目」的NSMutableArray中提取,該條目駐留在應用程序委託中。全局NSMutableArray似乎沒有價值

由於一些奇怪的原因,我可以在init函數中沒有問題地獲得這些值,但是進一步向下查詢類,我嘗試獲取這些值,並且應用程序崩潰而沒有錯誤消息(作爲示例,我放入了通過「populateFieldsForTouchedItem」方法訪問這些數據的「ccTouchBegan」方法)。

任何人都可以看到爲什麼這些值不能從其他方法訪問?在dealloc之前沒有對象被釋放。提前致謝!

@synthesize clicked, delegate, data, image, blurImage, normalImage, arrayOfRects, delegateEntries; 
- (id)initWithTexture:(CCTexture2D *)aTexture { 

    if((self=[super initWithTexture:aTexture])) { 
     arrayOfRects = [[NSMutableArray alloc] init]; 
     delegateEntries = [[NSMutableArray alloc] init]; 
     delegate = (InteractivePIAppDelegate *)[[UIApplication sharedApplication] delegate]; 
     delegateEntries = [delegate entries]; 
     data = [delegateEntries objectAtIndex:0]; 
     NSLog(@"Assigning %@", [[delegateEntries objectAtIndex:0] backgroundImage]); 
     NSLog(@"%@ is the string", [[data sections] objectAtIndex:0]); 
     //CGRect rect; 
     NSLog(@"Count of array is %i", [delegateEntries count]); 

     //collect as many items as there are XML entries 
     for(int i=0; i<[delegateEntries count]; i++) { 
      if([[delegateEntries objectAtIndex:i] xPos]) { 
       NSLog(@"Found %i items", i+1); 
       [arrayOfRects addObject:[NSValue valueWithCGRect:CGRectMake([[[delegateEntries objectAtIndex:i] xPos] floatValue], [[[delegateEntries objectAtIndex:i] yPos] floatValue], [[[delegateEntries objectAtIndex:i] xBounds] floatValue], [[[delegateEntries objectAtIndex:i] yBounds] floatValue])]]; 
      } else { 
       NSLog(@"Nothing"); 
      } 
     } 
     blurImage = [[NSString alloc] initWithString:[data backgroundBlur]]; 
     NSLog(@"5"); 
     normalImage = [[NSString alloc] initWithString:[data backgroundImage]]; 
     clicked = NO; 
    } 
    return self;  
} 

然後:

- (void)populateFieldsForTouchedItem:(TouchedRect)touchInfo 
{ 
    Data *touchDatum = [[Data alloc] init]; 
    touchDatum = [[self delegateEntries] objectAtIndex:touchInfo.recordNumber]; 
    NSLog(@"Assigning %@", [[[self delegateEntries] objectAtIndex:touchInfo.recordNumber] backgroundImage]); 
    rect = [[arrayOfRects objectAtIndex:touchInfo.recordNumber] CGRectValue]; 
    image = [[NSString alloc] initWithString:[[touchDatum sections] objectAtIndex:0]]; 
    [touchDatum release]; 
} 

- (BOOL)ccTouchBegan:(UITouch *)touch withEvent:(UIEvent *)event { 
    TouchedRect touchInfo = [self containsTouchLocation:touch]; 
    NSLog(@"Information pertains to %i", touchInfo.recordNumber); 
    if (!touchInfo.touched && !clicked) { //needed since the touch location changes when zoomed 
     NSLog(@"NOPE"); 
     return NO; 
    } 
    [self populateFieldsForTouchedItem:touchInfo]; 
    NSLog(@"YEP"); 
    return YES; 
} 

回答

1

它不是一個數組,它保存從代理的entries中抽取的值 - 它是完全相同的數組。您正在分配delegateEntries以指向代表的entries陣列。這意味着如果代理釋放它的數組,你正在訪問一個釋放的對象,並且你得到了你看到的結果。如果您想要委託人陣列的副本,請執行[[delegate entries] mutableCopy]

順便說一句,delegateEntries = [[NSMutableArray alloc] init]賦值只是一個內存泄漏,如果你正在做的立即分配變量指向委託的數組。你正在創建一個數組,不會釋放它,只是在下一步忘記它。

+0

謝謝查克!這個和ccTouchBegan運行後保留「touchDatum」的結合解決了我的問題。我會進一步測試以確保,但看起來不錯。感謝您的洞察! – diatrevolo 2010-05-19 18:10:04

2

改變了...

delegateEntries = [[NSMutableArray alloc] init]; delegateEntries = [delegate entries];

要這個......

delegateEntries = [[delegate entries] copy];

您目前正在泄漏內存。完成後釋放委託條目。

+0

共享委託的NSMutableArray仍然可能不是一個好主意。兩個對象共享可變狀態是很危險的。 – Chuck 2010-05-19 18:04:25

+0

謝謝迪倫的洞察力。上面我最終使用了查克的解決方案,但是感謝你指出了這一點。如果我有足夠的聲望,我會爲你們兩個投票。 – diatrevolo 2010-05-19 18:14:42