将NSMutableArray传递给其他类

时间:2009-03-19 10:34:27

标签: cocoa arrays import mutable

我在我的类loginController的实现中创建了一个NSMutableArray。可变数组包含一组字符串。我想将带有对象的可变数组传递给我的cocoa-project中的其他类。传递数组的最佳方法是什么?

4 个答案:

答案 0 :(得分:2)

最基本的情况是您的登录控制器只是将数组的快照交给另一个控制器。在这种情况下,您的登录控制器将需要引用其他类的实例,并将这些实例的某些属性设置为该数组。请记住使用copy属性声明属性,以便接收者不会保留您的私有可变数组。

如果你希望其他控制器能够修改数组,不要让他们拥有你的可变数组 - 这是一个难以发现的bug的邀请。

相反,您需要在登录控制器上实现一个属性,而不是在每个其他控制器上实现一个属性。登录控制器的属性至少应该包含一个getter和setter(您可以@synthesize),但是为了提高效率,您可以实现more specific accessor methods

拥有此属性后,其他控制器应以符合KVO的方式访问该属性。如果您实现特定的访问器,他们可以使用它们。否则,他们需要将mutableArrayValueForKey:发送到登录控制器。当他们访问该代理服务器阵列的内容时,他们真正访问了登录控制器的数组;当他们改变代理服务器阵列时,他们会依次改变登录控制器的数组。

接下来是实际的KVO部分。您希望其他控制器知道其中一个(或登录控制器)何时更改属性。让每个控制器(登录控制器除外)将其自身添加为登录控制器属性的观察者。请务必让他们使用-dealloc(或-finalize)方法删除自己。

为了发布正确的通知,所有内容都需要使用访问者或mutableArrayValueForKey:。这也适用于登录控制器本身 - 它应该在改变数组时使用自己的访问器,而不是直接传递数组。唯一的例外是在initdealloc中(因为访问者消息是对一半init ed / dealloc ked对象的消息,如果你有问题,这将是一个问题永远让访问者喜欢*)。

顺便说一句,听起来你可能有太多的控制器。看看你是否不能将一些逻辑转移到模型对象中。这大大简化了代码,因为Cocoa旨在与模型层一起使用。控制器很重,正在与框架作斗争,这为你做了更多的工作。

*“花哨”,我指的是除了给定访问器方法的正常行为之外的事情或者除此之外的事情。例如,insertObject:in<Foo>AtIndex:通常只是尾调用[<foo> insertObject:atIndex:];如果您将对象插入或存储在实例变量中的数组之外的某个位置,或者如果您在同一方法中执行其他操作(例如告诉视图需要显示它),那么您的存取方法很花哨。

答案 1 :(得分:1)

简短回答可能不是最佳做法:

[otherObject giveArray:[NSArray arrayWithArray:theMutableArray]];

答案 2 :(得分:0)

这个问题很好,但不完整......你只需要传递一个字符串数组,或者你要传递的类需要修改数组吗?

一般来说,简单地传递一个NSMutableArray *并不是一个问题,但是你需要小心,因为你只是传递一个指针(所以如果你把它保留在某处,你需要知道所有者或某些其他类可以修改数组)。 一般来说,你会想要使用NSMutableArray动态构建一个对象数组,当你需要共享它们时,然后制作一个不可变的副本并传递它。

 NSMutableArray* myArr = [NSMutableArray arrayWithObjects:@"1",@"2",@"3",@"four",nil];
 // maybe modify the array here...
 NSArray* nonMut = [[myArr copy] autorelease];
 [someObject doWork:nonMut];

| K&LT;

答案 3 :(得分:0)

我认为最适合您情况的模式是授权。您的LoginController不应该知道它将数据发送到哪个类。相反,您将实现LoginControllerDelegate协议

@protocol LoginControllerDelegate <NSObject>

@optional
- (void)loginController:(LoginController *)loginController didReceiveLoginIDs:(NSArray *)ids;

@end

然后,在您的LoginController课程中,您将实现这样的delegate属性:

@property (nonatomic, assign) id <LoginControllerDelegate> delegate;

然后,当你真正得到了与代表沟通的东西时,你会写下这个:

if ([self.delegate respondsToSelector:@selector(loginController:didReceiveLoginIDs:])
    [self.delegate loginController:self didReceiveLoginIDs:[NSArray arrayWithArray:loginIDs]];

应该接收登录ID的对象将包含LoginControllerDelegate协议,如下所示:

@interface SomeOtherClass : NSObject <LoginControllerDelegate>

您将在loginController:didReceiveIDs:中实施SomeOtherClass方法。

这样,您只需建立一种机制,将该数据发送到任何对其感兴趣的对象时,而不是您的LoginController需要对项目中的其他类有深入的了解。如果您以后更改哪个对象应该接收登录ID,则只需选择其他委托。