2014-04-30 4 views
0

내가 raywenderlich.com에 대한 몇 가지 자습서를 읽기, 코드 블록 우연히 봤는데을 구축하기 위해 동일한 변수를 사용하여 ... 아이폰 OS - 메모리 할당 - 배열

_players = [NSMutableArray arrayWithCapacity:20]; 

Player *player = [[Player alloc] init]; 
player.name = @"Bill Evans"; 
player.game = @"Tic-Tac-Toe"; 
player.rating = 4; 
[_players addObject:player]; 

player = [[Player alloc] init]; 
player.name = @"Oscar Peterson"; 
player.game = @"Spin the Bottle"; 
player.rating = 5; 
[_players addObject:player]; 

player = [[Player alloc] init]; 
player.name = @"Dave Brubeck"; 
player.game = @"Texas Hold’em Poker"; 
player.rating = 2; 
[_players addObject:player]; 

프로젝트 인 경우에도 ARC를 사용하면이 나쁜 코드가 아닌가요? 변수를 다시 할당하고 초기화 하시겠습니까? 한 번 할당하면 안되며 기존 데이터를 지워 재사용을 위해 변수를 준비하는 클래스 내의 메소드를 참조해야합니까?

+1

해당 코드가 잘못되었다고 생각합니까? 그것이'player' 변수를 재사용하는 데있어 전혀 문제가되지 않습니다. – rmaddy

답변

0

Danh의 대답은 아주 좋습니다.

"플레이어"와 같은 로컬 변수를 주차 공간으로 생각하십시오. 그것은 아무것도 (nil) 또는 차를 포함 할 수 있습니다.

공간에 차를 주차하고, 차에서 작업 한 다음 다른 곳으로 이동할 수 있습니다. 그런 다음 다른 차를 우주로 몰아 넣고 그 차에서 작업 한 다음 다른 곳으로 옮길 수 있습니다.

로컬 변수 플레이어는 Player 유형의 개체에 대한 포인터입니다. 그것은 nil로 시작합니다.

코드 player = [[Player alloc] init];을 실행하면 시스템에서 새 플레이어 개체에 대한 메모리를 할당하고 초기화 한 다음 해당 개체의 주소를 변수 player에 저장합니다. 코드는 새로 생성 된 Player 객체를 구성한 다음 변경 가능한 배열에 저장합니다. 배열은 새 객체에 대한 강력한 참조를 보유합니다.

이제 player = [[Player alloc] init]; 문을 다시 실행하면 완전히 새로운 플레이어 객체가 만들어지고 초기화되고 player 로컬 변수에 해당 NEW Player 객체에 대한 포인터가 저장됩니다. player에 있던 이전 값은 덮어 쓰여졌지만 이전 플레이어 개체가 _players 배열에 저장 되었기 때문에 괜찮습니다.

+0

"이전 플레이어 개체가 _players 배열에 저장되었습니다.". 배열 자체에 객체 자체가 아니라 객체에 대한 참조가 저장되어있는 경우가 아닌가? 객체 자체가 배열에 저장되어 배열 코드가 복사본을 만들었 기 때문에 op가 다시 사용하는 것에 대해 알았을 때 객체가 괜찮을 것입니다 (얕은 문제와 깊은 문제는 무시함). 그러나 그것은 상황이 아닙니다. – Gruntcakes

+0

+1 뛰어난 비유! – RyJ

+0

@Sausages, 네. 배열과 같은 컨테이너에 무언가를 저장할 때 실제로 저장하는 것은 객체에 대한 포인터입니다. ARC를 사용하면 객체에 대한 STRONG 참조가 저장되므로 객체가 메모리에 고정되어 할당 해제되지 않습니다. –

1

괜찮습니다. playerPlayer 개체에 대한 포인터가 저장되는 메모리 위치 일뿐입니다. 한 번에 하나씩 많은, 많은 Player을 가리킬 수 있습니다.

일부 심판은 변수가 주어진 범위에서 하나의 의미 적 목적으로 사용되어야한다는 말은 "귀여움"플래그를 던질 수 있습니다. 나는 응답으로 player 변수의 목적이 더 영구적으로 저장되기 전에 새로운 설정을하는 동안 새로운 변수를 보관하는 것이라고 주장 할 것입니다. 그것은 우리가이 범위에있는 동안 i 잘못 많은 값을 가정 것을 반대하지 않고

for (int i=0; i<MAX; ++i) 

말을하자 같은 인수입니다. i의 문제는 아닙니다. 그게 목적입니다.

+0

매우 근사합니다. 나는 사이트가 틀린 것을 게시 할 것이라고 생각하지 않을 것이다.) 그러나 나는 그것에 대해 물을 것이라고 생각했다. 감사! – RyJ

+0

그것이 바로 그가 말한 것입니다 : "한 번에." – Gruntcakes

+0

죄송합니다. 나는 어떤 이유로 "한 번에"그것을 잘못 읽었습니다. 신경 쓰지 마. :) – rmaddy

1

당신은 당신이있는 NSMutableArray를 호출 할 때 생각하고 있습니다 : 그것은 플레이어와 장소의 복사본 새로운 객체가 배열로하는 새로운 객체를 생성 addObject? 그 다음 당신의 코멘트를했다면

: ".. 기존 데이터를 닦아 재사용 변수를 준비하는 클래스 내에서 메소드를 참조하는 다음 번에 할당"작동합니다.

그러나 addObject 그렇게하지 않습니다, 그것은 배열에 플레이어 개체에 대한 참조를 추가하고 유지 수를 증가시킨다. 그래서 당신이 말한 것을 한 결과는 동일한 객체에 대한 다중 참조를 포함하는 배열이 될 것입니다. 배열을 반복하고 값을 출력하면 모두 동일하게 나타납니다. 그 이유는 배열에 다른 객체에 대한 고유 한 참조가 필요할 때 동일한 객체에 대한 여러 참조가 배열에 포함되어 있기 때문입니다.

명이 개체에 대해 수행

그대로 정확하지 않은 것을 (심지어 애플의 문서는이 실수를) 배열에 추가된다. 배열에 추가되는 객체 자체가 아니라 참조입니다. 이는 매우 중요한 차이점이며 Apple 문서는 오해의 소지가 있음을 비난해야합니다. 객체를 배열에 "추가"하는 것에 관해서는 어리숙하고 부정확 한 용어를 사용하는 모든 사람들이 그렇듯이 말입니다. 당신은 C/C++ 또는 유사한 배경에서 오는 경우

포인터의 배열이 아닌 객체의 배열로서 NSMutableArray를 생각한다.