将 NSMutableArray 传递给其他类

发布于 2024-07-16 00:54:32 字数 111 浏览 6 评论 0原文

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

I have created an NSMutableArray in the implementation of my class loginController. The mutable array contains a set of strings. I want to pass the mutable array with its objects to other classes within my cocoa-project. What is the best way to pass the array?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

心如狂蝶 2024-07-23 00:54:32

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

如果您希望其他控制器能够修改该数组,请不要让他们拥有您的可变数组,这会导致难以发现的错误。

相反,您需要在登录控制器上实现一个属性,而不是在每个其他控制器上实现一个属性。 登录控制器的属性至少应该有一个 getter 和 setter(您可以@synthesize),但您可以实现 更具体的访问器方法以提高效率。

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

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

为了发布正确的通知,所有内容都需要使用访问器或 mutableArrayValueForKey:。 这也适用于登录控制器本身——在改变数组时,它应该使用自己的访问器,而不是直接向数组发送消息。 唯一的例外是 initdealloc(因为访问器消息将是发给半inited/dealloc的消息code>ked 对象,如果您让访问器变得花哨,这将是一个问题*)。

顺便说一句,听起来你可能有太多的控制器。 看看是否无法将部分逻辑移至模型对象中。 这极大地简化了您的代码,因为 Cocoa 被设计为与模型层一起使用。 大量使用控制器就是与框架作斗争,这会给你带来更多的工作。

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

The most basic case is your login controller simply handing a snapshot of the array to the other controller. In this case, your login controller will need to have references to instances of the other classes, and it will set some property of those instances to the array. Remember to declare the properties with the copy attribute, so that the receivers don't hold on to your private mutable array.

If you want the other controllers to be able to modify the array, don't let them have your mutable array—that's an invitation to hard-to-find bugs.

Instead, you'll need to implement one property on the login controller, instead of one property on each of the other controllers. The login controller's property should have at least a getter and setter (which you can @synthesize), but you can implement more specific accessor methods for efficiency.

Once you have this property, the other controllers should access the property in a KVO-compliant way. If you implement the specific accessors, they can just use those. Otherwise, they'll need to send mutableArrayValueForKey: to the login controller. When they access the contents of that proxy array, they really access the login controller's array; when they mutate the proxy array, they mutate the login controller's array in turn.

Next comes the actual KVO part. You'll want the other controllers to know when one of them (or the login controller) changes the property. Have each controller (except the login controller) add itself as an observer of the property of the login controller. Remember to have them remove themselves in their -dealloc (or -finalize) methods.

In order for the right notifications to get posted, everything needs to use either accessors or mutableArrayValueForKey:. That goes for the login controller itself, too—it should use its own accessors when mutating the array, instead of messaging the array directly. The only exceptions are in init and dealloc (because the accessor messages would be messages to a half-inited/deallocked object, which will be a problem if you ever make the accessors fancy*).

BTW, it sounds like you may have way too many controllers. See if you can't move some of your logic into model objects instead. That drastically simplifies your code, as Cocoa is designed to work with a model layer. Being controller-heavy is fighting the framework, which makes more work for you.

*By “fancy”, I mean doing things other than or in addition to the normal behavior of a given accessor method. For example, insertObject:in<Foo>AtIndex: normally just tail-calls [<foo> insertObject:atIndex:]; if you insert or store the object somewhere other than in an array in an instance variable, or if you do something else in the same method (such as tell a view that it needs to display), then your accessor method is fancy.

江城子 2024-07-23 00:54:32

简短的回答可能不是最佳实践:

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

short answer that may not be the best practice:

[otherObject giveArray:[NSArray arrayWithArray:theMutableArray]];
失去的东西太少 2024-07-23 00:54:32

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

一般来说,简单地传递 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<

the question is a good one, but not complete... do you just need to pass an array of strings or does the class you are passing to need to modify the array?

In general, it's not a problem to simply pass around an NSMutableArray*, however you need to be careful, because you are just passing a pointer ( so if you retain it somewhere, you need to be aware that the owner or some other class may modify the array ).
generally spoken you would want to use NSMutableArray to dynamically build up an array of objects and when you need to share them, then make a non-mutable copy and pass that along.

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

|K<

姐不稀罕 2024-07-23 00:54:32

我认为最适合您情况的模式是授权。 您的 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 的对象,则只需选择不同的委托即可。

I think the pattern that's best for your situation is delegation. Your LoginController shouldn't have to know what class it's sending this data to. Instead, you would implement a LoginControllerDelegate protocol

@protocol LoginControllerDelegate <NSObject>

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

@end

Then, in your LoginController class, you would implement a delegate property like this:

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

Then, when you've actually got something to communicate to the delegate, you would write this:

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

The object that should receive the login IDs would incorporate the LoginControllerDelegate protocol like this:

@interface SomeOtherClass : NSObject <LoginControllerDelegate>

And you would implement the loginController:didReceiveIDs: method in SomeOtherClass.

This way, instead of your LoginController needing to have intimate knowledge of the other classes in your project, you simply establish a mechanism for sending that data to whatever object is interested in it when it becomes available. If you later change which object should receive the login IDs, you only need to choose a different delegate.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文