2013-08-18 3 views
1

나는 연결리스트를 구현하기 위해 노력하고있어에서 개체를 파괴, 그래서 내가 지금 같은 헤더 파일이있는 노드 클래스가 : 다른 클래스에서 다음목적-C

@interface Node : NSObject 

@property(nonatomic,assign)int data; 
@property(nonatomic,strong) Node *right; 
@property(nonatomic,strong) Node *left; 

@end 

을, 나는 그들에게 할당하고있어 방법을 여기에 자신을 것

Node *node0 = [[Node alloc]init]; 
Node *node1 = [[Node alloc]init]; 
Node *node2 = [[Node alloc]init]; 
Node *node3 = [[Node alloc]init]; 
Node *node4 = [[Node alloc]init]; 
node0.data = 1; 
node1.data = 2; 
node2.data = 5; 
node3.data = 5; 
node4.data = 3; 
node0.right = node1; 
node1.right = node2; 
node2.right = node3; 
node3.right = node4; 
node4.right = NULL; 
[self removeNodeWithValue:node0 value:5]; 
NSLog(@"node %d, %d, %d, %d, %d", node0.data, node1.data, node2.data, node3.data, node4.data); 

을 그리고 : 다음 주어진 값의 모든 발행 수를 파괴하는 방법을 호출

-(void)removeNodeWithValue:(Node *)head value:(int)value 
{ 
    Node *toDelete; 
    while (head != NULL) { 
    if (head.data == value) 
    { 
     toDelete = head; 
     head = head.right; 
     toDelete = nil; 
    } 
    else 
    { 
     head = head.right; 
    } 
    } 
} 
==> 1, 2, 5, 5, 3 

I toDelete = niltoDelete.data = 4으로 변경하면 출력이 ==> 1, 2, 4, 4, 3이므로 인스턴스를 변경할 수 있음을 알 수 있습니다. 내 질문은, 어떻게 그 인스턴스를 파괴합니까? 감사.

+0

다음을 참조하십시오 : http://stackoverflow.com/questions/14508134/whats-the-correct-way-destroy-different-kinds-of-objects-in-objective-c?rq=1 –

+0

그들은 객체를 무효로 만들지 만 내 코드에서는 작동하지 않는 것을 볼 수 있습니다. –

답변

3

ARC의 작동 방식을 이해하지 못한 것 같습니다. 오브젝트에 대한 강력한 포인터가있는 한, 오브젝트는 할당 해제되지 않습니다. 당신의 예에서 코드는 두 가지 이유로 실패 : 우선 당신은 항상 node0에 대한 강한 참조를 유지 :

Node *node0 = [[Node alloc]init]; 
만큼이 포인터가 규칙 NULL에 의해 nil (기억으로 설정되지 않는 한 정기적 인에 사용되는

포인터, 객체 포인터의 경우 nil), 노드는 할당 해제되지 않습니다.

둘째, 할당 해제 할 노드가 첫 번째 노드가 아닌 경우 강력한 포인터가있는 다른 노드가 있으며 이는 노드가 할당 취소되지 않는 또 다른 이유입니다. node0 (귀하의 경우 toDelete)을 가리키는 다른 포인터를 유지하면 노드의 노드 보유 횟수가 늘어나고 nil으로 설정하면 원래 값으로 돌아갑니다.

올바르게 삭제하려면 체인 삭제를 피하십시오 (첫 번째 노드가 할당 해제되면 두 번째 노드에 대한 강력한 참조가 손실되고 강력한 포인터가없는 경우 할당이 취소 될 수 있으며 할당 해제 될 세 번째 노드 등).

@interface List : NSObject 

@property (nonatomic, strong) Node* first; 
@property (nonatomic, weak) Node* last; 

@end 

// Inside the class implementation 

- (void) addNodeWithValue: (int) value 
{ 
    Node* node= [[Node alloc]init]; 
    node.data= value; 
    if(!first) 
    { 
     last= first= node; 
    } 
    else 
    { 
     last.right= node; 
     node.left= last; // left should be a weak property 
     last= node; 
    } 
} 

- (void) removeNodeWithValue: (int) value // O(n) method 
{ 
    Node* ptr= first; 
    while(ptr) 
    { 
     if(ptr.data== value) 
     { 
      if(ptr== first) 
      { 
       first= last= nil; 
      } 
      else 
      { 
       ptr.left.right= ptr.right; 
       ptr.right.left= ptr.left; 
      } 
      break; // Remove the break if you want to remove all nodes with that value 
     } 
     ptr= ptr.right; 
    } 
} 

I의 천국 '

마지막으로, 난 그냥 각 노드에 대한 포인터의 무리를 보유하지 않는 것이 좋습니다 대신 추가/제거 노드의 일을 할 것입니다 연결리스트 클래스를 구현 이 코드를 테스트 한 결과 작동하지 않을 수 있습니다.

+0

이것은 '5'들 중 하나를 없애고, 다른 5 개를 제거하기 위해 재귀 적으로 만들려고 시도했지만 아무 소용이 없습니다. –

+0

@ meta150이 코드는 하나의 값만 제거합니다. 모두 제거하려는 경우 루프 내에서 중단 명령 (주석에 의해 언급 됨 - 응답을 편집 함)을 제거해야합니다. –

0

그래서 모든 노드를 지정된 값으로 제거하려고합니다. 먼저, 모든 노드에 대한 명시적인 참조가 있기 때문에 테스트가 유효하지 않으므로 노드 구조에서 제거 되어도 테스트 로그가 출력합니다. 두 번째로, 제거 메소드는 테스트중인 노드가 지정된 값을 찾지 못하면 노드 구조를 재귀 적으로 호출해야합니다. 셋째, 노드 자체 테스트를해서는 안되며 leftright 노드 값을 테스트해야합니다. 노드는 부모를 모르기 때문에 자체를 제거 할 수 없습니다.

그래서, 뭔가 같은 :

-(void)removeNodeWithValue:(Node *)head value:(int)value 
{ 
    if (head.right.data == value) 
    { 
     head.right = nil; 
    } 
    else 
    { 
     [self removeNodeWithValue:head.right value:value]; 
    } 

    if (head.left.data == value) 
    { 
     head.left = nil; 
    } 
    else 
    { 
     [self removeNodeWithValue:head.left value:value]; 
    } 
} 

이것은 테스트하지 않습니다이 같은 루트 노드 자체가 시작하기 전에 확인해야 다음 컨트롤러 자체에서 머리 항목을 제거합니다.

0

문제는 포인터가 아니라 개체를 삭제하는 것입니다.

포인터는 내용 (메모리 위치)이있는 상자를 가리키는 화살표와 같습니다. 작업 할 때

toDelete = head; 
head = head.right; 
toDelete = nil; 

일부 상자에 poosing했지만 "상자"자체를 삭제하지 않고 "화살표"중 하나를 삭제하면됩니다.

와인의 대답은 올바른 접근 방식을 제공해야합니다.