2009-11-08 16 views
0

我做了以下內容:EXC_BAD_ACCESS在didAccelerate手機上的移動

- (void) accelerometer: (UIAccelerometer *)accelerometer didAccelerate: (UIAcceleration *)acceleration { 
if (self.lastAcceleration) { 
    double i = self.lastAcceleration.x; 

,直到我真正傾斜手機,它工作正常。然後我在最後一行得到EXC_BAD_ACCESS。 lastAcceleration是一個帶有保留的屬性。當我在調試器中查看「x」時,它具有很大的負值。爲什麼僅在傾斜時纔會拋出EXC_BAD_ACCESS異常?

- EDIT(因爲這個答案適用於下面的反應) -

我說這個,現在它的工作原理:

爲什麼會是怎麼回事?另外,它應該是

[self.lastAcceleration release]; 

我以前沒有在任何地方發佈lastAcceleration。以下是標題聲明:

@interface MyViewController : UIViewController <UIAccelerometerDelegate> { 
UIAcceleration *lastAcceleration; 
} 
@property(nonatomic, retain) UIAcceleration *lastAcceleration; 
@end 
+1

您需要額外提供更多的代碼。據推測,lastAcceleration值是在某處發佈的(或者不被保留,儘管你說過關於屬性聲明的內容)。 – 2009-11-08 08:14:16

+0

hmm。你能給出一些關於你的代碼應該做什麼的更多解釋嗎? – Morion 2009-11-08 08:16:19

+0

順便說一句,你爲lastAcceleration屬性分配內存? – Morion 2009-11-08 08:17:21

回答

1

我的預感是,加速度計API與崩潰無關,您顯示的代碼具有惡意內存管理的代碼,因爲您正在混合ivar和屬性訪問,我懷疑您可能在其他方面也做了相同的操作你沒有展示的部分。

反正一對夫婦的最佳實踐的東西:

  • 你有一個指針在你的類,你應該保留,任何物體相反,當你釋放你也應該ZAP公司指針,所以你不要冒這個險在它被釋放之後對其進行訪問(這個規則的例外是一些像委託對象這樣的模式,其中保留對象會導致保留週期,但這是一個整體的其他主題)
  • ivar setter和getters通過自動生成@synthesized指令會保留和釋放你的代碼的對象,它看起來像是分配一個指針,所以他們很漂亮方便,但財產訪問(self.something = ...)和伊娃爾訪問(東西= ...)是不相同的,所以你必須要小心

一個簡單的方法來確保你不混合兩個上是做這樣的事情:

@interface MyObject : NSObject 
{ 
    SomethingObject *_something; 
} 

@property (nonatomic, retain) SomethingObject *something; 

@end 

@implementation MyObject 

@synthesize something = _something; 

@end 

我們這裏所做的是讓伊娃和屬性名稱略有不同,讓你更清楚知道你正在使用其中一個,而編譯器如果你使用的話,會不會使用裸語法something = ...

現在的@ synthesize'd訪問器是這樣的:

- (void)setSomething:(SomethingObject *)newSomething 
{ 
    [newSomething retain]; 
    [_something release]; 
    _something = newSomething; 
} 

- (SomethingObject *)something 
{ 
    return _something; 
} 

與所有的出路,[lastAcceleration release]是一個壞事情,因爲它是不是也設置lastAcceleration指針爲零,你不能保證它不會被釋放,如果你不小心使用它,你很可能會崩潰。

[self.lastAcceleration release];是不正確的,因爲訪問器會爲您處理所有保留/發佈內容。

這裏要做的正確事情是self.lastAcceleration = nil;,如果您查看訪問器代碼,將釋放並將指針設置爲nil。

可能發生的情況是,您正在釋放lastAcceleration而沒有將其設置爲零,並且if (self.lastAcceleration) {檢查正在觸發釋放的對象。

+0

謝謝。也許這是另一個話題:應該只有ivars被設置爲零和屬性釋放,反之亦然? – 4thSpace 2009-11-09 16:19:08

+0

不要用單個前導下劃線來命名ivars。這是一個蘋果公司內部編碼慣例,他們採用這種慣例來減少您的代碼與他們的名稱發生碰撞的可能性。 – NSResponder 2009-11-09 20:42:34

0

EXC_BAD_ACCESS在您訪問釋放的內存時引發。我的猜測是你在某處發佈了self.lastAcceleration,但沒有將其設置爲空。

您確定它與傾斜有關嗎?

1

保留屬性的主要原因是爲了避免顯式的保留/釋放調用和與它們相關的內存管理錯誤。但在dealloc方法中,無論哪種方式都很好,因爲對象很快就會不復存在。 [self.lastAcceleration release]; - 不需要。

[lastAcceleration release]; self.lastAcceleration = nil; 

如果用在dealloc中,兩者都可以。 僅限dealloc使用

self.lastAcceleration = nil;