2013-05-26 3 views
2

[실행 취소 관리자 registerUndoWithTarget ::]을 사용하여 실행 취소 스택의 변경 사항을 추가하고 있습니다. 그러나 때로는 하나의 실행 루프 사이클에서 두 개의 변경 사항이 같은 그룹에 추가 될 때 가끔씩 되돌아옵니다. 이는 내가 원하지 않는 동작입니다. 이 두 가지 변경 사항을 분리하여 실행 취소 스택에 두 개의 항목을 포함하고자합니다. 올바르게 구현하는 방법은 무엇입니까? [NSObject performSelector :]를 사용하여 다음 실행 루프 사이클에서 두 번째 실행 취소 추가를 호출하거나 그 밖의 다른 작업을 호출 할 수 있습니까?NSUndoManager : 하나의 실행 루프 사이클에서 여러 변경 사항을 분리합니다

감사합니다.

답변

3

기본적으로 NSUndoManager은 한 실행주기에서 실행 취소 작업을 자동으로 그룹화합니다. 그러나 해당 동작을 변경할 수 있습니다. NO 인수를 보내면 -[NSUndoManager setGroupsByEvent:]은 자동 그룹화를 사용하지 않도록 설정합니다. 실행 취소 관리자가 -undo 또는 -undoNestedGroup을 실행하기 전에 모든 그룹을 닫아야합니다. 다른 Cocoa 클래스는 명시 적으로 그룹을 만들지 않고 실행 취소 작업을 등록하려고 할 수 있기 때문에 실행 취소 그룹을 등록하기 직전에 자동 그룹화를 비활성화하고 해당 그룹을 등록한 후에 다시 활성화 할 수 있습니다. 예를 들어

는 :

- (void)someMethod { 
    NSUndoManager *undoManager = …; // for example, [[self window] undoManager] 
    [undoManager setGroupsByEvent:NO]; 
    { 
     [undoManager beginUndoGrouping]; 
     { 
      [undoManager registerUndoWithTarget:modelObject selector:@selector(setString1:) object:[modelObject string1]]; 
      [modelObject setStringValue:newValue1]; 
      [undoManager setActionName:@"String 1 Change"]; 
     } 
     [undoManager endUndoGrouping]; 


     [undoManager beginUndoGrouping]; 
     { 
      [undoManager registerUndoWithTarget:modelObject selector:@selector(setString2:) object:[modelObject string2]]; 
      [modelObject setString2:newValue3]; 

      [undoManager registerUndoWithTarget:modelObject selector:@selector(setString3:) object:[modelObject string3]]; 
      [modelObject setString3:newValue3]; 

      [undoManager setActionName:@"Strings 2 and 3 Change"]; 
     } 
     [undoManager endUndoGrouping]; 
    } 
    [undoManager setGroupsByEvent:YES]; 
} 

-someMethod에서 세 변화는 string1, string2string3 및 속성을 수정 modelObject인가된다. string1에 적용된 변경 사항은 실행 취소 그룹의 일부이며 string2string3의 변경 사항은 다른 실행 취소 그룹의 일부입니다. 두 그룹은 실행 취소 관리자가 현재 실행 루프 사이클에 대한 기본 실행 취소 그룹의 모든 작업을 그룹화하지 않는 블록에 포함되어 있습니다. 이 방법을 실행하면 첫 번째 실행 취소 작업은 string2string3 변경 사항을 실행 취소하고 후속 실행 취소 작업은 string1에 적용된 변경 사항을 실행 취소합니다.

C 블록 {}을 사용하여이 두 계층 구조 (이벤트 및 실행 취소 그룹 별 그룹화 없음)를 명확하게 만듭니다.

NB : NSUndoManager이 아니고 스레드 안전.

+0

답변 해 주셔서 감사합니다. 문제의 또 다른 부분은 (내가 언급해야 함) 메시지를 등록 취소 할 때 NSTextView가 제어 할 수없는 부분이 있다는 것입니다. –

+0

@ NickolayOlshevsky 그리고 당신이 직면 한 정확한 문제는 무엇입니까? 나는 'NSTextView'로 빠른 응용 프로그램을 작성하고 잘 작동하는 것 같습니다 : 텍스트보기 실행 취소 작업은 스택을 실행 취소하고 사용자 정의 실행 취소 그룹과 별개입니다. –

+0

NSTextView에서 일부 텍스트를 편집하고 있습니다.이 레코드는 실행 취소 ('Undo Typing')됩니다. 그런 다음 항목을 다른 위치로 드래그하고이 드래그에 대해 실행 취소를 등록합니다. 그리고이 드래그 + 텍스트 타이핑은 하나의 실행 취소로 기록됩니다. 이것을 보면서 시간을 보내 주셔서 감사합니다. –