2012-05-20 2 views
0

TestFlight은 내 응용 프로그램에서 복제 할 수없는 오류를 확인했지만 문제가 해결되어야합니다. 오류는 unrecognized selector sent to instance 0x34a9e0입니다. GC가 제거한 객체에 locationId를 지정하려고하면 오류가 발생합니다.autorelease가 포함 된 iOS 메모리 관리

-[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이 값을 유지하기 위해 설정되지 않은 있습니다.

+0

참고 : iOS에는 가비지 수집기가 없습니다. – Caleb

답변

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

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

그래서 전송 셀렉터 locationId (게터가), setLocationId되지 않습니다 : (세터). 즉, 런타임에 setLocationId :를 호출하도록 속성을 설정하므로 자동 해제 된 객체 (이 경우 뷰 컨트롤러)가 오류의 원인입니다. 어딘가에서 할당 해제 된 _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의 게터를 호출하고 어떤 시점에서 당신은 아마 그것을 발표했다 당신의 _location.locationId, 함께 할 수있다. 코드의 수명주기가 _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]; 
} 

은 분명히 잘못되어 누출 될 것입니다. 이 autorelease하여 원래 버전처럼

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

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

,하지만 당신은 연기 할 때 일반적으로 단지 autorelease를 사용해야하기 때문에이 더 좋다 (이 경우에는하지 않는)에 release : 그것은해야합니다.

문제는보기 컨트롤러의 보유 개수가 아니지만 의심 할 여지없이 locationID 자체와 관련이 있습니다. 그 선언 (현재 클래스뿐만 아니라 PhotosViewController 클래스 내에서)을 우리와 공유 할 수 있습니까? 이게 뭐야? 어떻게 선언 되었습니까?