2012-05-20 49 views
0

TestFlight已確定在我的應用程序崩潰,我不能重複,但它發生了足夠的,我需要修復它。錯誤是unrecognized selector sent to instance 0x34a9e0,我認爲這是由於我嘗試將一個locationId分配給GC所消除的對象時造成的。iOS內存管理與autorelease

-[UIViewAnimationState locationId]: unrecognized selector sent to instance 0x34a9e0 

0 CoreFoundation 0x371e488f __exceptionPreprocess + 163 
1 libobjc.A.dylib 0x34ee9259 objc_exception_throw + 33 
2 CoreFoundation 0x371e7a9b -[NSObject doesNotRecognizeSelector:] + 175 
3 CoreFoundation 0x371e6915 ___forwarding___ + 301 
4 CoreFoundation 0x37141650 _CF_forwarding_prep_0 + 48 
5 Skate Spots 0x0000b9b9 -[DetailViewController handlePhotosButtonClick:] (DetailViewController.m:92) 
6 CoreFoundation 0x3713e3fd -[NSObject performSelector:withObject:withObject:] + 53 
7 UIKit 0x30ed3e07 -[UIApplication sendAction:to:from:forEvent:] + 63 
8 UIKit 0x30ed3dc3 -[UIApplication sendAction:toTarget:fromSender:forEvent:] + 31 
9 UIKit 0x30ed3da1 -[UIControl sendAction:to:forEvent:] + 45 
10 UIKit 0x30ed3b11 -[UIControl(Internal) _sendActionsForEvents:withEvent:] + 493 
11 UIKit 0x30ed4449 -[UIControl touchesEnded:withEvent:] + 477 
12 UIKit 0x30ec6b87 _UIGestureRecognizerUpdate + 5223 
13 CoreFoundation 0x371b8b1b __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 19 
14 CoreFoundation 0x371b6d57 __CFRunLoopDoObservers + 259 
15 CoreFoundation 0x371b70b1 __CFRunLoopRun + 761 
16 CoreFoundation 0x3713a4a5 CFRunLoopRunSpecific + 301 
17 CoreFoundation 0x3713a36d CFRunLoopRunInMode + 105 
18 GraphicsServices 0x338f9439 GSEventRunModal + 137 
19 UIKit 0x30ee6cd5 UIApplicationMain + 1081 
20 Skate Spots 0x0000325f -[Image willSendWithObjectLoader:] (Image.m:83) 
21 Skate Spots 0x00002b18 + 0 

原始編碼:

我假定自動釋放將這種方法的範圍的過程中保持的參考。

-(IBAction)handlePhotosButtonClick:(id)sender 
{ 
    PhotosViewController *vc = [[[PhotosViewController alloc] init] autorelease]; 
    vc.locationID   = _location.locationId; 
    [self.navigationController pushViewController:vc animated:YES]; 
} 

我的代碼更改:

我猜這將消除原有的錯誤,但這是做這件事的正確方法是什麼?

-(IBAction)handlePhotosButtonClick:(id)sender 
{ 
    NSLog(@"handlePhotosButtonClick");  
    PhotosViewController *vc = [[[PhotosViewController alloc] init] retain]; 
    vc.locationID   = _location.locationId; 

    [self.navigationController pushViewController:vc animated:YES]; 
    [vc release]; 
} 

編輯

你們是正確的_location沒有設置保留價值。

@property (nonatomic, readwrite, assign) RKLocation *location;

+0

注意:iOS中沒有垃圾回收器。 – Caleb

回答

0
-[UIViewAnimationState locationId]: unrecognized selector sent to instance 0x34a9e0 

所以發送的選擇是locationId(吸氣劑),不setLocationId:(裝定)。這意味着,這不是自動釋放的對象(在這種情況下,您的視圖控制器)會導致錯誤,因爲您設置了它的屬性,因此運行時會調用setLocationId:on。它是評估某個地方取消分配的_location對象,然後另一個對象接管它的指針(在這種情況下它是一個UIViewAnimationState),當然它不響應locationId getter。嘗試修改您的代碼,以便在您需要其屬性之前,_locationId變量不會被釋放。

1
PhotosViewController *vc = [[[PhotosViewController alloc] init] retain]; // <--- this is over retaining and it's totally wrong, because init method returns an already retained object. 

錯誤與您_location.locationId,它調用的_location getter和在某些時候,你可能已經發布了它做。檢查您的代碼的生命週期_location,並且最好使用屬性而不是實例變量。

0

關於你的代碼,你的原代碼更接近你想要的。值得注意的是,你的最終代碼:

-(IBAction)handlePhotosButtonClick:(id)sender 
{ 
    NSLog(@"handlePhotosButtonClick");  
    PhotosViewController *vc = [[[PhotosViewController alloc] init] retain]; 
    vc.locationID   = _location.locationId; 

    [self.navigationController pushViewController:vc animated:YES]; 
    [vc release]; 
} 

是絕對錯誤的,並會導致泄漏。它應該是:

-(IBAction)handlePhotosButtonClick:(id)sender 
{ 
    NSLog(@"handlePhotosButtonClick");  
    PhotosViewController *vc = [[PhotosViewController alloc] init]; 
    vc.locationID   = _location.locationId; 

    [self.navigationController pushViewController:vc animated:YES]; 
    [vc release]; 
} 

這就好比你原來的版本autorelease,但是這是更好,因爲當你需要推遲你通常應該只使用autoreleaserelease(你在這種情況下沒有)。

您的問題不在視圖控制器的保留計數,但無疑與locationID本身有關。你能和我們一起分享(在PhotosViewController類以及當前類中)的聲明嗎?它是什麼?它是如何宣佈的?