문제

다음 구조가있는 NSDocument가 있습니다.

@interface MyDocument : NSDocument
{
    NSMutableArray *myArray;

    IBOutlet NSArrayController *myArrayController;
    IBOutlet MyView *myView;
}
@end

나는 mydocument.xib의 nsarraycontroller와 myview를 인스턴스화하고 파일의 소유자 (myDocument)에 연결 했으므로 인터페이스 빌더의 관점에서 모든 것을 올바르게 수행했다고 확신합니다.

MyView의 인터페이스는 간단합니다.

@interface MyView : NSView {
    NSMutableArray *myViewArray;
}
@end

지금에 MyDocument windowControllerDidLoadNib, 다음 코드가 있습니다.

- (void)windowControllerDidLoadNib:(NSWindowController *) aController
{
    [super windowControllerDidLoadNib:aController];
    [myArrayController setContent:myArray];
// (This is another way to do it)    [myArrayController bind:@"contentArray" toObject:self withKeyPath:@"myArray" options:nil];

    [myView bind:@"myViewArray" toObject:myArrayController withKeyPath:@"arrangedObjects" options:nil];
}

디버거에서 나는 그것을 확인했다 myViewArray NSControllerArrayProxy이므로 프로그래밍 방식의 바인딩이 정확한 것으로 보입니다. 그러나 MyView의 메소드에 MyView에 객체를 추가하려고 할 때 myViewArray, 그들은 myDocument의 업데이트되지 않는 것 같습니다. myArray. 나는 다음 두 가지 접근법을 모두 시도했다.

[myViewArray addObject:value];
[self addMyViewArraysObject:value];

(두 번째 접근법은 예상대로 컴파일러 오류를 일으키지 만 객체 C 런타임이 KVO에 대한 제한된 이해에 따라이 방법을 "구현"할 것이라고 생각했습니다.)

내가 업데이트하는 방법에 문제가 있습니까? myViewArray? 프로그래밍 방식의 바인딩에 문제가 있습니까? (MyView는 사용자 지정보기이고 IB 팔레트를 만들고 싶지 않기 때문에 프로그램적 으로이 작업을 수행하려고합니다.)

도움이 되었습니까?

해결책

문제는 배열을 직접 돌연시키고 있다는 것입니다. 구현하다 색인 액세서 방법 그리고 그것들을 부릅니다.

KVO는 액세서 방법을 무시합니다 (귀하가 준수하는 한 특정 형식) 및 필요한 알림을 게시합니다. 배열과 직접 대화 할 때 이것을 얻지 못합니다. 부동산에 묶인 것은 당신이 명시 적으로 말하지 않으면 부동산을 변경했다는 것을 알지 못합니다. 액세서 방법을 사용하면 KVO가 다른 개체를 알려줍니다.

액세서 방법 (합성 또는 기타)을 사용하지 않는 유일한 시간은 init 그리고 dealloc, 당신은 절반과 대화 할 것이기 때문에inited 또는 -deallocKED 대상.

자신의 액세서 방법을 사용하여 배열을 돌연변이하고 무료 KVO 알림을 받으면 상황이 작동해야합니다.

  • 자산을 돌출 할 때 View는 배열 컨트롤러에 자동으로 알리고, content 컨트롤러를 통지하는 속성.
  • 컨트롤러는 자산을 돌릴 때 배열 컨트롤러에 자동으로 알리고, arrangedObjects 뷰를 알리는 속성.

다른 팁

여기서는 두 가지 가능성을 볼 수 있습니다.

먼저, 당신은 인스턴스화합니까? NSMutableArray 당신의 객체 (그리고 그것을 릴리스) MyDocument 수업? 다음과 같이 보일 것입니다.

- (id)init
{
    if ((self = [super init]) == nil) { return nil; }
    myArray = [[NSMutableArray alloc] initWithCapacity:0];
    return self;
}

- (void)dealloc
{
    [myArray release];
    [super dealloc];
}

둘째, MyViewArray를 속성으로 선언 했습니까? MyView? 다음과 같이 보일 것입니다.

// MyView.h:
@interface MyView : NSView
{
    NSMutableArray * myViewArray;
}
@property (assign) NSMutableArray * myViewArray;
@end
    // MyView.m:
    @implementation MyView
    
    @synthesize myViewArray;
    
    @end
    

    그 외에, 그것은 당신이 모든 바인딩을 제대로 한 것처럼 보입니다.

    업데이트: 사용하는 것은 어떻습니까 NSArrayController 배열에 항목을 추가하려면 :

    // MyView.h:
    @interface MyView : NSView
    {
        NSMutableArray * myViewArray;
        IBOutlet NSArrayController * arrayController;
    }
    @property (assign) NSMutableArray * myViewArray;
    - (void)someMethod;
    @end
    
      // MyView.m:
      @implementation MyView
      
      @synthesize myViewArray;
      
      - (void)someMethod
      {
          id someObject = [[SomeClass alloc] init];
          [arrayController addObject:[someObject autorelease]];
      }
      
      @end
      

      문제는 내가 MyView의 구속력을 묶은 것 같습니다. myViewArray NSARRAYCONTROLLER에 arrangedObjects 그 대신 속성 content 재산.

      바인딩 할 때 arrangedObjects, 나는 실제 물체가 myViewArray 인스턴스였습니다 NSControllerArrayProxy. 온라인에서 더 많은 정보를 얻기 위해이 객체가 실제로 무엇을하는지에 대한 확실한 답을 찾지 못했습니다. 그러나 내가 찾은 코드 예제는 NSControllerArrayProxy가 배열의 객체의 속성, 배열 자체의 물체보다는. 이것이 내가 구속력이 있다고 믿는 이유입니다. arrangedObjects.

      해결책은 대신 MyView의 바인드를 바인딩하는 것이 었습니다 myViewArray NSARRAYCONTROLLER에 content 재산:

      - (void)windowControllerDidLoadNib:(NSWindowController *) aController
      {
          [super windowControllerDidLoadNib:aController];
      
          [myArrayController setContent:myArray];
          [myView bind:@"myViewArray" toObject:myArrayController withKeyPath:@"content" options:nil];
      }
      

      이것이 효과가있는 것처럼 보이지만, 나는 결합하는 것이 옳다고 확신하지 않습니다. content 이 경우. NSARRAYCONTROLLER의 다양한 속성에 프로그래밍 방식으로 구속력을 밝힐 수 있다면이 답변에 대한 의견을 환영합니다. 감사.

      우선, 배열과의 바인딩에는 아무런 문제가 없습니다. 예를 들어, NSTABLECOLUMN은 해당 내용이 배열로만 바인딩되어야하며, 내용 값은 rateDobjects.someProperty에 대한 내용을 가져야합니다.

      일반적인 실수는 배열 공장을 ArrayController의 내용으로 간주하는 것이지만, 보았 듯이, 슬픔으로 이어질 것입니다. 배열 도체는 ArrayController가 현재 콘텐츠 자체가 아니라 컨텐츠의 객체를 배열 한 방식을 나타냅니다.

      즉, 배열을 ArrayController에 바인딩하는 방법은 다음과 같습니다.

      [self.myArrayController bind:NSContentArrayBinding 
       toObject:self
       withKeyPath:@"myView.myViewArray" 
       options:nil]; 
      

      그건 그렇고, 당신의 견해는 myviewarray를 유지해야합니까? 일반적으로 컨트롤러 또는 모델 객체의 책임에 속합니다.

      이제 addobject를 호출하여 객체를 추가 할 수 있습니다 ArrayController에서, 그것은 컨트롤러의 책임이기 때문에.

      [self.myArrayController addObject: anObject]
      
      라이센스 : CC-BY-SA ~와 함께 속성
      제휴하지 않습니다 StackOverflow
      scroll top