NSUserDefaults에 NSDate를 저장하는 가장 좋은 방법은 무엇입니까?


174

NSUserDefaults에 NSDate를 저장하는 두 가지 방법이 있습니다.

옵션 1-setObject : forKey :

// Set
NSDate *myDate = [NSDate date];
[[NSUserDefaults standardUserDefaults] setObject:myDate forKey:@"myDateKey"];

// Get
NSDate *myDate = (NSDate *)[[NSUserDefaults standardUserDefaults] objectForKey:@"myDateKey"];

옵션 2-timeIntervalSince1970

// Set
NSDate *myDate = [NSDate date];
NSTimeInterval myDateTimeInterval = [myDate timeIntervalSince1970];
[[NSUserDefaults standardUserDefaults] setFloat:myDateTimeInterval forKey:@"myDateKey"];

// Get
NSTimeInterval myDateTimeInterval = [[NSUserDefaults standardUserDefaults] floatForKey:@"myDateKey"];
NSDate *myDate = [NSDate dateWithTimeIntervalSince1970:myDateTimeInterval];

장점과 단점

옵션 1

이것은 작고 논리적 인 것 같습니다. 그러나 Date Formatter 버그로 인해 이것이 잘못 될 염려가 있습니다.

옵션 2

서투른 것 같습니다. NSTimeInterval에 "subsecond 정확도"가 있다고 말한 애플 문서에도 불구하고 한 번의 테스트에서 날짜를 다시 검색했을 때 48 초가 지났다.

요구 사항

어떤 방법을 선택하든 다음과 같아야합니다.

  1. 1 초 안에 정확합니다.

  2. 읽기 쉽고 신뢰할 수 있습니다.

내 질문

내가 잘못하고 있기 때문에 옵션 2의 부정확성이 있습니까?

이 두 가지 옵션 중 어느 것을 사용 하시겠습니까?

내가 모르는 다른 옵션이 있습니까?

감사!

답변:


380

불필요하게 복잡한 일이 있습니다. 왜 날짜를 시간 간격으로 변환 한 다음 (시간 간격을 다른 프리미티브로 변환)? 그냥 [sharedDefaults setObject:theDate forKey:@"theDateKey"]끝내세요. NSDate는 PLIST 형식 (날짜, 숫자, 문자열, 데이터, 사전 및 배열)이 지원하는 "주요 유형"중 하나이므로 직접 저장할 수 있습니다.

증거 는 설명서 를 참조하십시오 .

날짜를 직접 저장하고 검색하기 만하면 올바른 일을 할 수 있습니다 (시간대, 정밀도 등 포함). 다른 사람들이 말했듯이 포매터는 없습니다.


8
여호수아, 대답 해 주셔서 감사합니다. 내가 바보 같은 플로트 접근법을 시도한 이유는 다른 위대한 개발자가 그것을 보았 기 때문에 그가 좋은 이유 때문에 그렇게했다고 생각했기 때문입니다. 당연히 아니. 나는 setObject : forKey :를 사용하고 자신의 본능에 대해 더 많은 확신을 가져야한다.
John Gallagher

7
필자는 불필요한 합병증이라는 생각에 대해 매우 폭력적입니다. 개발자와 일반적으로 게으른 사람들에게 좋은 특성입니다. :-)
Joshua Nozzi

이러한 접근 방식이 사용되는 경우는 대부분 NSUserDefaults가 일반 미들웨어에 대한 사용자 기본 설정의 스토리지 구현으로 사용되는 경우입니다.
Coyote

@Coyote :이 경우 여전히 NSUserDefaults를 통해 액세스하거나 속성 목록 파일에서 구문 분석되므로 동일한 액세스 또는 구문 분석에서 적절한 NSDate 오브젝트를 생성해야하며 필요에 따라 변환 할 수 있습니다.
Joshua Nozzi

3
@JohnGallagher [사이드 바] 가난한 사람을 위해 누군가의 특정 구현을 착각하지 마십시오. 귀하의 원래 감정은 "좋은 이유가 있다고 생각했습니다 ... 아마도 그렇지 않습니다"는 귀하가 해당 개발자의 요구 사항의 전체 범위를 이해 한 경우에만 유효 할 수 있습니다. 그의 접근 방식을 "이런 식으로 할만한 확실한 이유가 없다"고 맹목적으로 표시하는 것은 추측적이고 친밀한 생각이다. 즉, 당신이 달리 할 이유가 없다면 간단하게 유지하려는 Joshua의 접근 방식에 동의합니다.
dooleyo

14

옵션 # 1의 경우 날짜 포맷터가 포함되어 있다고 생각하지 않습니다. 아마 후드 아래에 있지만 그것이 깨지지 않았다고 생각합니다. 날짜는 ISO 8601 형식으로 저장됩니다 .

옵션 # 2, 사용 -setDouble:forKey:-doubleForKey대신의 float기반 버전. 정밀도 오류의 원인이 될 수 있습니다.


와, 존 매우 빠른 답변에 감사드립니다. 어떤 것을 개인적으로 사용 하시겠습니까?
John Gallagher

8
시간 간격이 아닌 날짜를 직접 사용하십시오. 너무 많은 앱이 의존 할 때 그러한 기본 API가 깨질 것입니다.
John Calsbeek

우수한. 그건 내 직감 이었지만 float 메소드를 사용하는 존경받는 개발자가 타사 코드를 보았으므로 그것을 사용했을만한 이유가 있다고 생각했습니다. 당연히 아니. 귀하의 답변에 다시 한번 감사드립니다!
John Gallagher

1
본 코드는 속성 목록에 어떤 유형을 직접 저장할 수 있는지 기억하지 못하는 개발자 일 수 있습니다.
John Calsbeek

2
레코드의 경우 32 비트 부동 소수점의 정확도는 24 비트이므로 1970 년에서 현재 40 년으로 40 * 365 * 86400 초이며 (40 * 365 * 86400) / (2 ** 24) = 75 초 오류입니다. . 배정도는 DateTime 간격이며 RAW 정밀도는 이제 백만 분의 1 초보다 낫습니다.
Tom Andersen

5

NSUserDefaults를 사용하십시오. 날짜는 Zulu 시간으로 저장되므로 걱정할 시간대 문제가 없습니다. 표준 시간대에 저장하고 다른 표준 시간대에서 꺼내면 괜찮습니다. 시스템에서 변환을 처리합니다 (걱정할 날짜 포맷터 없음).


0

Facebook Graph API에서 만료 날짜를 저장하는 경우 * 옵션 2 *를 사용 합니다.

옵션 2는 쉽게 stringWithFormat을 사용하여 문자열로 변환 할 수 있습니다. 가장 중요한 것은 Graph API에서 작동합니다.

또한 날짜 형식에 대해 걱정할 필요가 없습니다. NSDateFormatter를 다루지 않으면 48 초 오류의 가능성이 있습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.