2016-08-11 9 views
2

저는 신속하게 익숙하지 않아 옵션 값을 올바르게 사용하는 방법을 실제로 이해하지 못합니다.신속한 옵션 값에 대해 혼동 스럽습니다.

상황은 다음과 같습니다. 첫째, 특성 클래스의 일부 값을 저장하고 값을 얻기 위해 서버에 요청을 보내는 모델 클래스가 있습니다. 코드 :

import Foundation 

class User: NSObject { 

    var name: String? 

    func getInfo(updateUI:() ->()) { 
     let manager = AFHTTPSessionManager() 
     manager.POST(URLString, parameters: nil, success: { (task: NSURLSessionDataTask, responseObject: AnyObject?) in 

      let dic = responseObject as? NSDictionary 
      self.name = dic?.objectForKey("name") 
      updateUI() 

     }, failure: { (task: NSURLSessionDataTask?, error: NSError) in 
      log.obj(error) 
    }) 

} 

둘째, 나는 서버 및 업데이트 UI에서 값을 얻기 위해의 ViewController에서이 모델을 사용하고 싶습니다. 코드 :

class UserViewController: UIViewController { 

    @IBOutlet var nameLabel: UILabel! 
    var user = User() 

    override func viewDidLoad() { 
     super.viewDidLoad() 

     user.getInfo({ 
      nameLabel.text = user.name! 
     }) 
    } 

} 

는 나는 내가 라벨에 넣어 할 때 특정 이름을 보장 할 수 있습니다 아무것도 없기 때문에이 일을 처리하는 위험한 방법입니다 생각합니다. 대부분의 경우에 잘 작동하지만 서버에서 올바른 값을 가져 오지 못하면 충돌 할 수 있습니다 (예 : 키 "name"에 대한 값 없음). 이 같은 값 unwarp 전에 var name = ""

  • 시험 :

    1. 같은 속성에 대한 기본값을 보내기

      나는 위의 질문에 대해 두 개의 아이디어가

      if let foo = user.name { 
          nameLabel.text = foo 
      } 
      

    첫 번째 방법을 선택하고 싶습니다.

    1. 레이블에 기본 문자열을 표시하는 것이 선택 값을 손상시키지 않으므로 충돌보다 훨씬 수용 가능하다고 생각합니다.
    2. 사용할 값이 더 많으면 코드가 길어지고 읽을 수 없습니다.

    올바른 것을 선택 했습니까? 또는 둘 다 선택적인 가치의 사용을 이해하지 못했고 더 좋은 방법이 있습니까? 누군가 나를 도울 수 있니?

  • +0

    내가 상자에서 즉시 생각할 수있는 한 가지 사실은 무한 값으로 끝난 변수에 메모리를 할당하고 있다는 것입니다. 따라서 지금까지 필요한 것보다 더 많은 메모리를 할당하고 있습니다. (이 할당은 무시할 만하다. 고려해야 할 사실이다.) – Harsh

    +2

    기본값 접근법 ('var name = ""')을하고 싶지 않다. 선택적 바인딩 ('if name = user.name {nameLabel.text = name}')은 _unwrap_ 옵션으로 확실히 이동하는 방법입니다. 아니면 pbrush25가 보여준대로'nil' 콜렉시 화 연산자'''를 사용하십시오. 그러나 "이름이 없을 때 무엇을 표시해야합니까?"라는 질문은 사용자 인터페이스 질문입니다 (레이블의 '텍스트'설정시). 일반적으로 모델에 넣으려는 것이 아닙니다. 모델에 데이터가 없을 때'nil' 옵션을 사용하는 것이 올바른 접근 방식입니다. – Rob

    답변

    3

    안전하게 옵션을 푸는 정도와 같은 새로운 변수 선언하지 않고 그것을 디폴트 값을 제공 할 수 있습니다 :이 전무 병합 연산자라고하며 선택적인 랩을 해제하려고합니다

    nameLabel.text = user.name ?? "" 
    

    을하고 포장을 벗긴 경우 이것이 성공하지 못하면 연산자의 rhs에 놓은 기본값을 제공합니다.

    3

    선택 사항 인 언 래핑 옵션이 올바르지 않은 본능이 정확합니다. nil이 아닌 기본값을 제공하면 선택 사항의 목적을 무효화하는 것도 올바른 것입니다.

    if let foo = user.name 바인딩이 일의 사운드 방법이지만, 당신이하고있는 모든 값을 할당하는 경우 pbush25이 상태로, 당신은 전무 병합 연산자를 사용하여 자신에게 중괄호를 마련 할 수있는 :

    nameLabel.text = user.name ?? "Default Label Text"

    "unwrap user.name을 의미하고 해당 값이 nil이 아닌 경우 사용하십시오. 그렇지 않으면 다음 값을 사용하십시오."예를 들어 사용자 ID를 폴백 레이블로 사용하려는 경우 텍스트가 있지만 ID가 존재하지 않을 수도 있습니다 :

    nameLabel.text = user.name ?? user.id ?? "No name or ID".

    선택적 값이 nil 인 경우 충돌이 발생하는 경우에도 적어도 오류 메시지를 제공 할 수 있도록 선택 사항의 강제 적용을 해제하는 것보다 assert을 사용하거나 preconditionFailure()을 사용하는 것이 좋습니다.