2011-10-02 1 views
0

, 난 그냥 수행NSTimer의 메모리 관리 - 변수에 할당해야합니까? 내가 타이머를 만들고 싶어 할 때마다

[NSTimer scheduledTimerWithTimeInterval:5.0 
           target:self 
           selector:@selector(someMethod) 
           userInfo:nil 
           repeats:NO]; 

오히려

NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:5.0 
                target:self 
               selector:@selector(someMethod) 
               userInfo:nil 
               repeats:NO]; 

보다 첫 번째는 메모리 누수인가? 그들을 사용하는 올바른 방법은 무엇입니까?

답변

6

스 니펫에 아무런 메모리 문제가 없습니다. 타이머와 상호 작용할 필요성을 선택하기 만하면됩니다.

당신은 타이머를 예약 할 때, 실행 루프를 유지하고, 타이머에 대한 참조가 선택기는 화재 때 함께 전달된다 - 예를 들어, (void) doTimerThing: (NSTimer *)tim1이 - 사용되는, 그래서 아니다 엄격하게을 변수에 넣고 보유해야합니다. Apple은 Timer Programming Topics doc의 "Memory Management" section에서이 점을 매우 명확하게 설명합니다.

그러나 타이머를 무효화하려면이 발생하기 전에 (또는 반복 타이머의 발생 사이에) 참조가 필요합니다. 이 경우 retain으로 전화하는 것도 좋습니다. scheduledTimerWithTimeInterval:target:... 메서드는 소유하지 않은 개체를 반환하므로 소유자가 소유하지 않은 개체의 메모리 상태 (autorelease 풀에 있는지 여부, 실행 루프가 얼마나 오래 지속되는지 여부 포함)에 대한 가정을해서는 안됩니다 타이머를 주변에 두십시오). 타이머 (또는 임의의 객체)가 주위를 둘러 쌀 필요가있는 경우 retain을 호출하여 소유권 주장을해야합니다.


1하는 것으로 타이머의 방법해야 항상 have one parameter; 귀하의 스 니펫에있는 선택 도구는 그렇지 않은 방법에 대한 것처럼 보입니다. 타이머는 그런 식으로 작동하지만 문서화 된 인터페이스와는 반대로 작동합니다.

+0

항상 하나의 매개 변수가 있어야한다는 것은 무엇을 의미합니까? – Snowman

+2

내가 포함 된 스 니펫을보고 링크 된 문서를 읽으십시오. 타이머의 메소드는 'NSTimer'의 인스턴스 인 하나의 인수를 취할 수 있어야합니다. –

3

어느 쪽이든 메모리 누수가 없습니다. 두 번째 솔루션은 결과에 변수에 영향을주는 반면 첫 번째 솔루션은 결과를 저장하지 않지만 효과는 동일합니다.

명명 규칙에서 알 수 있듯이 메서드의 이름이 scheduledTimerWithTimeInterval:... 인 경우 자동 다시 렌더링 된 개체 을 반환합니다 (또는 사용자가 소유자가 아닌 개체를 반환합니다.

필요하지 않은 경우 생성 된 NSTimer에 대한 참조를 보유 할 필요가 없습니다. 타이머가 RunLoop에서 예약됩니다 (RunLoop이 실행됩니다). 그것이 사용될 때까지 그것을 유지하고, 끝낼 때 그것을 풀어 라. 그래서 당신은 성가심을 가질 필요가 없다. 그래서 그것은 스스로 살 것이다.

두 번째 코드와 같은 변수에 NSTimer 변수를 저장하지 않으면 원할 경우 타이머를 취소 할 수 없습니다. 특히 반복 타이머를 설정 한 경우 나중에 액세스 할 수 있도록 변수에 저장해야합니다. 특히 취소 할 수 있도록 invalidate 메시지를 보내야합니다.당신이 반복 타이머가 필요하지 않은 경우

+0

'scheduledTimerWithTimeInterval :'autoreleased 객체를 반환하지 않습니다. 호출자가 소유하지 않은 오브젝트를 리턴합니다. –

+0

그래,하지만 내 편집 내용을 읽었을 때 (다른 주석과 마찬가지로) 내가 실제로 의미하는 바를 설명하고 내가 의미하는 바를 정확하게 설명했다. (그리고 내가 신중히 읽었을 때 이미 편집 전에도 RunLoop 타이머 유지) – AliSoftware

+1

자동 해제 풀에있는 개체는 다른 개체가 소유 할 수 있으며 호출자가 소유하지 않은 개체는 자동 해제 풀에있을 필요가 없습니다. 그것들은 똑같지는 않으며, 서로 얽매어서는 안됩니다. –

3

이전 답변에 추가하여, 대신 수동으로 타이머를 만드는

[self performSelector:@selector(someMethod) withObject:nil afterDelay:5.0]; 

를 사용할 수 있습니다.

+0

멋지다, 몰랐다! – Snowman

+0

여기에 어떤 이점이 있습니까? 실제로는 없습니까? – Snowman

+0

@mohabitar : 이것은 무대 뒤에서 타이머를 생성하며, 일정 기간 동안 메소드의 실행을 지연시키는 더 직접적이고보다 읽기 쉬운 방법입니다. –