代码之家  ›  专栏  ›  技术社区  ›  erikprice

如何将对象添加到程序绑定的NSmutableArray中?

  •  1
  • erikprice  · 技术社区  · 16 年前

    我有一个NSdocument,其结构如下:

    @interface MyDocument : NSDocument
    {
        NSMutableArray *myArray;
    
        IBOutlet NSArrayController *myArrayController;
        IBOutlet MyView *myView;
    }
    @end
    

    我在mydocument.xib中实例化了nsarraycontroller和myview,并与文件的所有者(mydocument)建立了连接,因此我很确定从Interface Builder的角度来看,我做的一切都是正确的。

    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时 米维射线 ,它们似乎没有更新mydocument的 myArray . 我尝试过以下两种方法:

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

    (正如预期的那样,第二种方法会导致编译器错误,但我认为Objective-C运行时会根据我对kvo的有限理解“实现”这个方法。)

    我想更新的方式有什么问题吗 米维射线 是吗?我的程序绑定有问题吗?(我正尝试通过编程实现这一点,因为MyView是一个自定义视图,我不想为它创建一个ib调色板。)

    4 回复  |  直到 15 年前
        1
  •  1
  •   Peter Hosey    16 年前

    问题是您正在直接改变您的数组。实施 indexed accessor methods 打电话给他们。

    kvo重写访问器方法(只要符合 certain formats )并张贴必要的通知。当您直接与数组交谈时,不会得到这个结果;除非您明确地告诉它,否则绑定到该属性的任何内容都不会知道您已经更改了该属性。当使用访问器方法时,kvo会告诉其他对象。

    唯一不使用访问器方法(合成或其他)的时间是 init dealloc 因为你要和一半的人说话- 初始化 ED或 释放内存 KED对象。

    一旦您使用自己的访问器方法来改变数组,从而获得免费的kvo通知,事情就可以正常工作了:

    • 当改变其属性时,视图将自动通知数组控制器,该控制器将改变其属性 content 属性,通知控制器。
    • 当您的控制器改变其属性时,它将自动通知数组控制器,数组控制器会改变其属性。 arrangedObjects 属性,通知视图。
        2
  •  1
  •   James Eichele Bernard Igiri    16 年前

    我在这里可以看到两种可能性:

    首先,您是否实例化 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
        
        3
  •  1
  •   erikprice    16 年前

    问题似乎是我一直在绑定我的视图 myViewArray 去NSarraycontroller's arrangedObjects 属性而不是其 content 财产。

    当绑定到 排列对象 我发现 米维射线 NSControllerArrayProxy . 当我在网上搜索关于这个物体的更多信息时,我没有找到一个确切的答案。但是,我发现的代码示例建议nsControllerArrayProxy用于公开访问 数组中对象的属性 而不是对象本身。这就是为什么我认为我在约束 排列对象 .

    解决方案是改为绑定MyView的 米维射线 去NSarraycontroller's 内容 财产:

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

    虽然这似乎有效,但我不能100%确定是否正确绑定到 内容 在这种情况下。如果有人能从程序上了解到NSarrayController的各种属性的绑定,我将欢迎对这个答案的评论。谢谢。

        4
  •  1
  •   Elise van Looij    15 年前

    首先,绑定到arrangedObjects没有错:例如,一个instableColumn的内容应该只绑定到arrangedObjects,其contentValues则绑定到arrangedObjects.someProperty。

    常见的错误是将arrayController的内容视为arrayController的内容,但正如您所见,这将导致悲伤:arrayController是arrayController当前在其内容中安排对象的方式的表示,而不是内容本身。

    也就是说,将数组绑定到ArrayController的方法是:

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

    顺便问一下,您确定您的视图需要保存MyViewArray吗?这通常由控制器或模型对象负责。

    现在可以通过调用addobject添加对象 在阵列控制器上 因为这是管制员的责任。

    [self.myArrayController addObject: anObject]