2012-02-26 2 views
0

나는 learnig objective-c 및 iPad 앱 프로그래밍 과정을 진행 중입니다. 내가 계속해서 스스로를 트립하고 다시 읽어야하는 한 가지는 메모리 관리입니다. 나는 거기에 도착하고있다. .. 천천히. 모든 기본 규칙은 alloc/retain과 같이 release이어야합니다. 그러나 한 상대적으로 기본적인 것은 저를 회피한다 누군가가 설명 할 수 있는지 궁금 ... ios에서의 메모리 관리 이해

NSArray *myArray = [[NSArray alloc] init]; 
myArray = [someNSSet allObjects]; 

이 비교적 똑바로 앞으로 코딩되어 ... 다음 코드를 가지고와 [myArray release] 문을 필요로한다.

NSArray *myArray = (NSArray *)[someNSSet allObjects]; 

까지 내가 이해를 사용할 때 어떻게 당신이 그나마 (NSString *) 필요 ...

는 그러나, 나는의 예를보고 유지 (실제로, 나는 광범위 다음 '바로 가기'를 사용했다 [myArray release] 문을 사용하여,하지만 난 이유를 이해 해달라고합니다.

수 누군가가 설명 할 수 있을까?이 코드는를 유출

답변

1

: 배열의 크기는 0이다 NSArray를 불변 인 점을 명심 때문에 일부 메모리 량 어레이 (할당되는

NSArray *myArray = [[NSArray alloc] init] 

실제로이 경우에는 무의미하다!). 변수 myArray는 예약 된 메모리 영역의 첫 번째 바이트 주소를 보유합니다.

이제 두 번째 줄에서 [someNSSet allObjects]가 저장된 메모리 영역의 첫 번째 바이트를 가리키는 myArray 값을 변경합니다. 이 순간에 배열이 어디에 저장되어 있는지 처음부터 알지 못합니다. 그래서 누수가 생겼어.

라인 :이 시점에서 어떤 메모리를 예약하지 않기 때문에

NSArray *myArray = (NSArray *)[someNSSet allObjects]; 

, 맞습니다. ARC를 사용하지 않을 경우 참조 된 메모리 블록에서 GC를 멀리하기 위해 retain을 호출 할 수 있습니다. 다른 방법으로 개체 소유자가 이탈하고 예를 들어 액세스하려고하면 BAD_EXEC가 표시 될 수 있습니다. [myArray objectAtIndex : 0]

2
NSArray *myArray = [[NSArray alloc] init]; 
myArray = [someNSSet allObjects]; 

을은 첫 번째 줄에 할당 한 NSArray에 대한 참조를 잃어 버리기 때문에 발생합니다. 두 번째 줄에 myArray에 새 값을 할당하기 때문에 여기에 alloc이 필요하지 않습니다.

NSArray *myArray = (NSArray *)[someNSSet allObjects]; 

이 코드 예제는 완벽하게 괜찮습니다, 당신은 [someNSSet allObjects] 포인터 myArray의 결과를 할당하고 당신이 그것을 해제 걱정하지 않아도 당신은 반환 값을 보유하고 있지 않습니다.

프로젝트에 대해 ARC (Automatic Retain Counting)를 사용해보십시오. ARC를 사용하면 컴파일러가 보유 개수를 관리하므로 실제로 그렇게 할 필요가 없습니다. 현재 프로젝트를 변환 할 리팩토링이 있습니다.

+0

반환 값을 소유하고 있지 않는 이유는 무엇입니까? 누구/무슨 일이야? –

+0

@BenThompson : 객체 (new 또는 alloc, copy 또는 mutableCopy)를 만들 때 보유 개수가 1이고 소유하고있는 객체입니다. 개체를 보낼 때 메시지를 보관할 때 보유 수는 1 씩 증가하며 사용자가 소유하고 있습니다. 자신이 소유 한 객체 만 릴리스하면됩니다. –

+1

@Ben : 자동 회수 풀이'allObjects'에서 반환 된 객체의 소유자 일 가능성이 큽니다. 다른 가능성은 set 객체입니다 만, 이것은 새로운 배열을 생성하기보다는 세트가 이미 소유 한 객체를 노출 한 경우에만 실제로 발생합니다. 그러나 배경에서 무슨 일이 벌어지고 있는지에 대한 이해를 제외하고, 당신은 자신의 물건을 소유하고있는 자신을 염려해서는 안됩니다. 당신이하든 안하든, 당신이 고려해야 할 전부입니다. –

2

당신이 말했듯이, 게시 한 첫 번째 코드에는 누수가 있습니다. 당신이 alloc, new 또는 copy, 당신이 그것을 소유로 시작하는 방법을 통해 오브젝트를 취득 할 때, 사실

NSArray *myArray = [[NSArray alloc] init]; 
[myArray release]; 
myArray = [someNSSet allObjects]; 

, 당신은 그것을 해제해야합니다 : 그래서 당신은 릴리스를 추가해야합니다. 그래서 여기에서 alloc 메서드를 사용하여 얻은 배열을 해제해야합니다. 이 규칙을 사용하면 개체를 소유 한 시점과 그렇지 않은 시점을 쉽게 알 수 있습니다. 따라서 기억하십시오 : alloc, new 또는 copy.

두 번째 예제에서 세 단어 (alloc, new 또는 copy) 중 하나로 시작하지 않는 방법으로 배열을 얻었으므로 객체를 소유하지 않으며 사용자가 책임지지 않습니다. 그것을 공개했다. 사실, 당신이 얻은 배열은 자동 회수 된 객체입니다. 즉, 보유 개수가 현재 1이지만 자동 회수 풀이라는 것이 고갈되면 자동으로 해제됩니다.

여기에 대한 참조는 Memory Management Rules입니다.첫 줄

+0

은 답안 코드에서 3 번 줄을 더 잘 뒤집을 수 있습니다 (또는 release 대신 autorelease를 사용하십시오). – meronix

+0

2 행의'release'는 2 행의'alloc'의 균형을 맞추기 위해'myArray'의 이전 값 누출되지 않습니다. myArray에 새로운 값을 할당하기 전에 그렇게해야합니다. – sch

+0

네, 물론 그렇습니다.하지만 릴리스하면 3 행에서 myArray가 더 이상 존재하지 않으며 더 이상 할당되지 않고 오류가 발생할 수 있으며 사용할 수 없습니다. alloc과 release의 균형을 맞추고 두 줄 사이에서 객체를 사용해야합니다. 안 그래? – meronix