2012-10-08 54 views
2

我想了解自動引用計數,因爲我來自高級編程語言(Python),而且我正在使用Objective-C的這一特性的項目。我經常遇到ARC解除分配我以後需要的對象的問題,但現在我有一個具體的例子,我希望我能得到一個解釋。爲什麼我的NSArray被釋放?

- (void) animateGun:(UIImageView *)gun withFilmStrip:(UIImage *)filmstrip{ 
    NSMutableArray *frames = [[NSMutableArray alloc] init]; 
    NSInteger framesno = filmstrip.size.width/gun_width; 
    for (int x=0; x<framesno; x++){ 
    CGImageRef cFrame = CGImageCreateWithImageInRect(filmstrip.CGImage, CGRectMake(x * gun_width, 0, gun_width, gun_height)); 
    [frames addObject:[UIImage imageWithCGImage:cFrame]]; 
    CGImageRelease(cFrame); 
    } 
    gun.image = [frames objectAtIndex:0]; 
    gun.animationImages = frames; 
    gun.animationDuration = .8; 
    gun.animationRepeatCount = 1; 
    [gun startAnimating]; 
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW,(arc4random() % 300)/100 * NSEC_PER_SEC), dispatch_get_current_queue(),^{ 
    [self animateGun:leftGun withFilmStrip:[self getFilmStripForAction:gunShoot andTeam:nil withWeapon:nil]]; 
    }); 
} 

這段代碼的代碼背後的想法很簡單:我有一個(UIImageView*)gun我與存儲在(NSMutableArray *)frames,在隨機時間的圖像動畫。 (UIImage *)filmstrip只是一個包含所有將用於動畫的幀的圖像。動畫作品的第一次迭代,但問題出現在第二次迭代中,我得到-[UIImage _isResizable]: message sent to deallocated instance ...-[UIImage _contentStretchInPixels]: message sent to deallocated instance ...-[NSArrayI release]: message sent to deallocated instance ...。這發生在

gun.animationImages = frames; 

但我不明白爲什麼。我並沒有要求解決我的問題,而只是爲了幫助我理解這裏發生的事情。謝謝。

+0

代碼你如何調用這個函數?多次被稱爲? –

+0

我第一次用'[self animateGun:leftGun withFilmStrip:[self getFilmStripForAction:gunShoot andTeam:nil withWeapon:nil]]來調用它;'然後我離開'dispatch_after'完成它的工作。 – ov1d1u

+1

對我來說,似乎UIImageView和UIImage引用是問題,而且錯誤在於此方法之外。 – Mike

回答

0

ARC是一種無需手動保留/釋放對象的機制。這是一個很好的網站,解釋如何工作:http://longweekendmobile.com/2011/09/07/objc-automatic-reference-counting-in-xcode-explained/

嘗試更改「leftGun」爲「槍」。如果你通過伊娃使用它,我想這可能是某個時候被釋放的那個。否則,LeftGun根本不在範圍內。

下面是它應該是什麼樣子:

在您的.h文件中:

@property (nonatomic, strong) IBOutlet UIImageView *leftGun; 

在您.m文件:

dispatch_after(dispatch_time(DISPATCH_TIME_NOW,(arc4random() % 300)/100 * NSEC_PER_SEC), dispatch_get_current_queue(),^{ 
    [self animateGun:gun withFilmStrip:[self getFilmStripForAction:gunShoot andTeam:nil withWeapon:nil]]; 
    }); 

而且,不太肯定 「gunShoot」來自。這應該是一個枚舉?

EDIT

添加的leftGun屬性應該如何定義的例子。在法國國內使用財產背後的原因是內存管理的目的。如果要釋放或銷燬屬性的對象,只需將其設置爲零,並且該屬性將負責在需要時釋放該對象。

+0

但是函數的每次調用都不是'frames'重新創建的嗎? – ov1d1u

+0

啊!你是對的。但是,「leftGun」和「gunShoot」在哪裏聲明? –

+0

leftGun是在類的@接口中聲明的IBOutlet。 'gunShoot'只是'enum'中的一個項目,它用於決定在'getFilmStripForAction'中使用哪個圖片。com/fBu1mUZ2 – ov1d1u

-1

如果您將其標記爲__block,您可能會阻止frames陣列的重新分配。

__block NSMutableArray *frames = [NSMutableArray array]; 

看到「The __block Storage Type.」

+0

該數組在塊內部沒有使用,而且它不是早期發佈的數組。它似乎是陣列中的物體。 –

+0

該數組在塊內用作'gun.animationImages = frames;'的引用,它持有圖像的引用。 – Tassos

+0

該部分不在塊內。 –

相關問題