2012-09-17 3 views
4

2 개의 컨트롤러, BarViewController 및 FooViewController가 있다고 가정 해보십시오.왜 객체가 segue를 통해 올바르게 전달되지 않습니까?

FooViewController가있는 UIImageView라는 이미지 뷰에 배출구를 가지고

@property (nonatomic, weak) UIImageView *imageView; 

BarViewController가있는 UIButton 버튼 출구를 갖는다. BarViewController에는이 버튼에서 BarToFooSegue (스토리 보드에서 수행됨)라는 FooViewController에 대한 segue가 있습니다.

다음 코드를 실행하고 FooViewController.imageView.image에서 NSLog를 호출하면 결과가 nil이되어 내 이미지가 표시되지 않습니다. 왜 이런 경우입니까?

// code in BarViewController 
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{ 

    if([segue.identifier isEqualToString:@"BarToFooSegue"]){ 
     NSURL *photoUrl = @"http://www.randurl.com/someImage"; // assume valid url 
     UIImage *image = [UIImage imageWithData:[NSData dataWithContentsOfURL:photoUrl]]; 
     UIImageView *imageView = [[UIImageView alloc] initWithImage:image]; 

     [segue.destinationViewController setImageView:imageView]; 
    } 
} 

내가 대신 약한 강한로 FooViewController.imageView 설정을 시도했지만 문제가 남아 :

@property (nonatomic, strong) UIImageView *imageView; 

내 디버거를 실행, 나는 FooViewController의 이미지 뷰가 prepareForSegue 내부에 올바르게 업데이트주의 사항 :하지만 그 다음 몇 라인을 다시 갱신 한 다음 @property 이미지가 nil로 설정된 새롭게 할당 된 imageView로 다시 가져옵니다. 나는 그것이 어셈블리 언어로 작성된 줄에서 발생했기 때문에 컨트롤 흐름의 어떤 부분이 이것을 일으키는 지 잘 모르겠습니다.

// code in BarViewController 
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{ 

    if([segue.identifier isEqualToString:@"BarToFooSegue"]){ 
     NSURL *photoUrl = @"http://www.randurl.com/someImage"; // assume valid url 
     UIImage *image = [UIImage imageWithData:[NSData dataWithContentsOfURL:photoUrl]]; 

     [segue.destinationViewController setMyImage:image]; 
} 

및 수정 viewWillAppear 다음 대신 이미지 뷰의 이미지를 전달하는 BarViewController에 :

@property (nonatomic, strong) UIImage *myImage; 

및 prepareForSegue 변경 : 나는 FooViewController에있는 UIImage 속성을 추가하여 작업 내 코드를 가지고

: FooViewController에서 :

- (void)viewWillAppear:(BOOL)animated{ 
    [self.imageView setImage:self.myImage]; 
} 

답변

6

이미지를 설정하기 전에 [segue.destinationViewController view];으로 전화하면보기 계층이로드되고 출력이 설정됩니다.

+1

+1입니다. 그것을 (무효로) 던지고 좋은 말을 써라. :-) – danh

+1

정말 좋은 해결책입니까? 메모리가 부족하면 언제든지보기 제어기의보기를 언로드하고 필요할 경우 다시로드 할 수 있습니다. 그러므로'viewDidLoad'에서'imageView'를 설정하는 것이보다 견고한 해결책이 될 것 같습니다. –

+0

신중하게 사용하면 실용적인 해결책이라고 생각합니다. 어떤 패턴과 마찬가지로, 남용과 오용은 물론 가능합니다. 상황에 따라 imageView는 대상이 실제로 신경 쓰지 않는 장식을위한 컨테이너이므로 UIImage를 임시 저장하는 속성을 추가 한 다음 viewDidLoad에 설정하면 작은 의미 론적 값에 지나치게 복잡해 보입니다. Segue를 준비 중이기 때문에보기가로드 될 것입니다. 약간 이전에로드하도록 강요하면 접착제 코드를 작성하지 않아도됩니다. – ikuramedia

2

prepareForSegue 매장은 아직 정의되지 않았습니다. 당신은 nil에 메세지를 보내고 있습니다. 이것은 아무 문제가 없으므로 오류는 아니지만,이 경우에 예기치 않은 동작이 발생할 수 있습니다. 임시 UIImage 속성을 만들어 문제를 해결하고 viewDidLoad 또는 viewWillAppear에서 이미지보기를 해당 이미지로 설정합니다.

+0

죄송합니다. [segue.destinationViewController setImageView : imageView]를 말하고 있습니까? segue.destinationViewController가 nil이므로 아무 일도하지 않고 있습니까? – Popcorn

+0

FooViewController에서 임시 UIImage 속성을 만들지 않아도됩니다. 분명히 깔끔한 해결책이 있어야합니까? – Popcorn

+0

대상 뷰 컨트롤러가 nil이 아니지만 imageView가 있습니다. prepareForSegue에 이미지 뷰를 로깅하여 테스트 할 수 있습니다. nil을 반환합니다. 그리고 불행히도, 이것이 완료된 방법입니다. iOS 6에서는이 문제가 해결되었지만 iOS 5 용으로 빌드해야하는 경우에는 이렇게해야합니다. –

-1
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{ 

    if([segue.identifier isEqualToString:@"BarToFooSegue"]){ 
        NSURL *photoUrl = @"http://www.randurl.com/someImage"; 
        UIImage *image = [UIImage imageWithData:[NSData dataWithContentsOfURL:photoUrl]]; 

    
     FooViewController *vc = [segue destinationViewController]; 
     vc.myImage = image; 
} 
} 
+0

이것은이 문제의 해결책과 동일한 코드입니다.본인은 주로이 문제가 발생한 이유에 관심이 많으며 주위를 둘러 볼 수있는 더 좋은 방법이 있다면 – Popcorn

1

imageView.image를 직접 설정해야하는 경우 @ikuragames 대답에 동의합니다. 그러나 일반적으로 내 ViewController의 뷰 계층 구조는 비공개로 유지합니다.

Foo에 UIImage 속성을 추가하는 것은보기 흉한 것으로 생각하지 않습니다. 나는 그것이 실제로 올바른 해결책 인 @ikuragames보다 더 예쁘다고 생각한다.

관련 문제