“仅数据”的更好替代方案Objective-C 对象?

发布于 2024-08-22 09:10:24 字数 1022 浏览 5 评论 0原文

我经常遇到这样的设计选择,并且有点挣扎;我正在寻找其他一些观点。

我经常想保留列表或传递基本上只是值集的状态块。这些值往往是原始类型:浮点数、NSTimeIntervals、CGPoints 等。

我的第一个倾向通常是为这些属性集创建 C 结构,例如

typedef struct _STATE {
    float foo;
    NSTimeInterval elapsed;
    CGPoint point;
} STATE;

等。

但是 C 结构与本机 Cocoa 集合类(< code>NSArray、NSSetNSDictionary),并且使用过多的它们来跟踪大量状态感觉就像它违背了我的 Cocoa 的其余部分 -友好的代码——我最终拥有并直接管理结构数组,并在消息中传递结构指针等。

另一方面,由于原始性能不一定很重要,我可以将这些值编码到 NSDictionary 中,将它们包装起来全部都在 NSValueNSNumber 中,但生成的语法很难简洁,而且有点脆弱,需要在运行时插入和查找的类型和名称正确性:

[stateDict setObject:[NSNumber numberWithFloat:foo] forKey:@"bar"];
... 
float something = [[stateDict objectForKey:@"bar"] floatValue];

以及一些像 NSTimeInterval 这样的类型只能与一些(有争议的)黑客技术一起使用(在这种情况下类型转换为 double)。

最后,我可以创建纯数据容器对象,其中包含私有成员数据和仅 getter/setter。 (这些在 Java 中被称为“bean”。)它们比字典更易于访问,比结构更 Cocoa,但对我来说感觉有点矫枉过正,特别是如果我只需要它们作为用于状态管理的“内部类”单个对象类型的内部。

伟大的 Cocoa 编程公众,你是如何做到这一点的?

I run into design choices like this often and struggle a bit; I'm looking for some other perspectives.

I often want to keep lists of, or pass around chunks of state that are basically just sets of values. The values tend to be primitive types: floats, NSTimeIntervals, CGPoints, etc.

My first inclination is often to create C structures for these sets of properties, e.g.

typedef struct _STATE {
    float foo;
    NSTimeInterval elapsed;
    CGPoint point;
} STATE;

etc.

But C structures don't play nicely with the native Cocoa collection classes (NSArray, NSSet, NSDictionary), and using overmany of them to track lots of state feels like it runs against the grain of rest of my Cocoa-friendly code-- I end up having and directly managing arrays of structs, and passing struct pointers around in messages, etc.

On the other hand, since raw performance isn't necessarily critical, I could encode these values into a NSDictionary, wrapping them all in NSValue or NSNumber, but the resulting syntax is hardly terse, and a little fragile, requiring type and name correctness at runtime for both the insert and the lookup:

[stateDict setObject:[NSNumber numberWithFloat:foo] forKey:@"bar"];
... 
float something = [[stateDict objectForKey:@"bar"] floatValue];

and some types, like NSTimeInterval, are only able to be used with some (arguable) hackery (typecast to double in that case).

Finally, I could create data-only container objects, with private member data and only getters/setters. (These would be called "beans" in Java.) These are more terse to access than dictionaries, more Cocoa than structs, but feel like overkill to me, especially if I only need them as "inner classes" that are used for state management internal to a single object type.

How do you, great Cocoa programming public, do this?

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

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

发布评论

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

评论(2

咽泪装欢 2024-08-29 09:10:24

根据具体情况,我可以使用 NSDictionary 类来处理任意数据,也可以创建容器类(Objective C 中的 @property/synthesize 标签使这变得非常简单)。通过使用 ObjC 作为头文件:

@interface StateObject : NSObject {
    NSNumber *foo;
    NSTimeInterval *elapsed;
    CGPoint point;
}

@property (retain) NSNumber *foo;
@property (retain) NSTimeInterval *elapsed;
@property (copy)   CGPoint point;

@end

然后可以在 .m 文件中使用 @synthesize 自动创建 setter/getter。然后,虽然匿名 NSNumber 仍然很烦人,但您可以这样做:

myStateObject.foo = [NSNumber numberWithFloat:7.0];

这应该会消除大部分痛苦,并让您使用 Cocoa 集合类更好地调整数据。

Depending on the situation, I run either with using NSDictionary classes for arbitrary data, or I create container classes (the @property/synthesize tags in Objective C make this really easy). By using ObjC for the header file:

@interface StateObject : NSObject {
    NSNumber *foo;
    NSTimeInterval *elapsed;
    CGPoint point;
}

@property (retain) NSNumber *foo;
@property (retain) NSTimeInterval *elapsed;
@property (copy)   CGPoint point;

@end

One can then use @synthesize <variable> in the .m file to automatically create the setters/getters. Then, while anonymous NSNumbers are still ornery, you can do:

myStateObject.foo = [NSNumber numberWithFloat:7.0];

This should take most of the pain away, and let you use the Cocoa collection classes to better shuffle data around.

灵芸 2024-08-29 09:10:24

不一定认可这种方法为“最佳”,但您的建议之间有一个中间立场:创建 C 结构来保存信息,然后在需要将结构放入 NSValue 对象时将其包装在 NSValue 对象中可可数据结构。您可以看到 UIKit 在某些情况下使用通知中的 CGPoint 等结构来执行此操作(我确信 AppKit 也这样做)。

请参阅 Cocoa 的数字和值编程主题 了解更多相关信息。

Not necessarily endorsing this approach as "best", but there is a middle ground between your proposals: create C structs to hold the information, and then wrap the structs in NSValue objects when you need to put them into Cocoa data structures. You can see UIKit do this in some cases with structs like CGPoint in notifications (and I'm sure that AppKit does, as well).

See "Using Values" in Number and Value Programming Topics for Cocoa for more on that.

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