Objective-C联合体 "->"与"."的区别

5

首先,我要说我对结构体和联合体还比较陌生。在发布这篇文章之前,我已经做了功课,并且真诚地想要得到合法的澄清。如果这样做是错误的,请告诉我。首先,我尝试创建一个联合体,因为我正在组合不同的数据类型。我唯一真正的问题/问题是点运算符与->运算符的区别。我可以使用点运算符获得我想要的结果。

->

但不包括

.

我很好奇为什么要这样做?我在 Stack 上阅读了许多帖子,展示了使用“。”的示例或“答案”,但在现实世界中没有运气。我已经尝试过类似于“typedef”的东西...

typedef union _myUnion
{
     int intValue;
     bool boolValue;
}myUnion;

但这似乎没有什么区别。如果有人能解释一下我做错了什么,那将不胜感激。这是我尝试做的一个快速示例。为了简单起见,我只会发布一些结构体/联合体语法,并不添加任何子类代码,因为这不是问题。

示例.h

#import "<Foundation/Foundation.h"

union myUnion
{
   int intValue;
   bool boolValue;
};

@interface MyClass : NSObject
{
    union myUnion *someProperty;
}

@property (nonatomic, assign) union myUnion *someProperty;

-(void)doSomething;

@end

example.m

#import "MyClass.h"

@implementation MyClass

@synthesize someProperty = _someProperty;

- (id)init
{
//Some init method...
}

- (void)doSomething
{
    NSLog(@"I Did Something...");
}

@end

现在在我的另一门课程中,这个功能可以正常使用...


MyClass *newObject = [MyClass alloc] init];
newObject.someProperty->intValue = 6;

但是这并不意味着...
MyClass *newObject = [MyClass alloc] init];
newObject.someProperty.intValue = 6;

目前,我更感兴趣的是了解为什么后者不起作用?有趣的是,如果我在属性的.h文件中去掉指针。

@interface MyClass : NSObject
    {
        union myUnion someProperty;
    }

@property (nonatomic, assign) union myUnion someProperty;

"."可以替代"-",但现在它不能被赋值。另外一件事,如果我将bool更改为int并将其作为struct,同样的事情也会发生。不幸的是,我先学习了Objective-C,而且在慢慢学习严格的C语言过程中。所以我对C的理解有点薄弱,但这就是Obc的优美之处,我可以用同样的精力学习两种语言!如果不算OpenGL的话。
我想问一下,是否有人可以发布一个可工作的代码示例,然后我就可以找出我做错了什么,或者彻底解释一下我的问题和我错过的一些基本概念。从那里开始,我就可以找出如何编写自己的有效代码了。我不需要两者都有,也不期望得到援助,但我希望能够学习,以便能够解决自己的问题,而不只是在不了解其原因或原理的情况下修补有错误的代码。
2个回答

8
a->b 运算符是 (*a).b 的简写,它类似于使用 . 但需要先进行解引用。当 a 是一个指针时,这种方式是合适的。
由于在您原始的示例中,someProperty 是一个指向联合体的指针,因此您需要先对该指针进行解引用。这意味着您需要使用以下其中一种方法:
(*newObject.someProperty).intValue // confusing!

或者

newObject.someProperty->intValue // much better

访问它。

当然,一旦您将someProperty从指针更改为联合体,则可以使用。 所以:

  • a->b: 访问指针上的结构体/联合体成员
  • a.b: 访问原始结构体/联合体上的成员

5
在这种情况下,你很可能希望将联合体作为一个值而不是指向外部内存位置的指针:
@interface MyClass : NSObject
{
    union myUnion someProperty; // << no '*'
}

@end

然后你使用句点进行成员访问:

someProperty.intValue = 6;

如果这是一个指针,那么:

someProperty->intValue = 6;

然而,还有另一个问题。在使用联合作为属性时,你有两个(主要)选项。值或指针。通常使用值来处理,尤其是当所有字段都引用结构/联合体本地内存且字段不是很大时。在这种情况下,你通常会通过值来返回和设置。这意味着你的程序将被编写如下:

@interface MyClass : NSObject
{
    union myUnion someProperty;
}

@property (nonatomic, assign) union myUnion someProperty; // << by value

@end

然后客户端可以通过值来访问和设置它,如下所示:

union myUnion p = obj.someProperty;
++p.intValue;
obj.someProperty = p;

这通常是通过不涉及共享资源的小结构来实现的。

当您选择直接访问字段时,如果您的实例可以直接访问,则不需要副本:

- (void)doSomething
{
  ++someProperty.intValue;
}

如果这变得复杂,将数据抽象成方法后,访问和修改应该留给持有联合的 MyClass 实例。

你和Timothy提供的答案非常清晰明了,谢谢你们。如果我可以问一个后续问题。假设我正在创建普遍存在的“人”类。该“人”具有“头发”属性。该头发具有“长度”和“颜色”。因此,如果我想设置person.hair.color = black; & person.hair.length = long; 那么结构体是否是正确的选择,还是应该考虑其他方法?我想知道如何创建“子属性”,然后设置和获取这些属性。 - DoS
再次感谢您提供的信息。但是,正如您所说,我只是想学习不同的方法论来完成任务,以此来“开阔我的视野”。我知道我可以使用纯O-C类来实现这一点,但我很好奇还有其他什么方法可以做到。我想我对我的伪“子属性”问题或语法还有点困惑。以“人”类为例,您基本上是在说“头发”只是“人”类的一个子类。然后,“长度”和“颜色”只是头发子类的属性?我理解得对吗? - DoS
@DoS 最终取决于复杂性和行为。对于给定的任务或实现,一个结构体(C结构体或Objective-C类)通常更有利。在人的情况下,你最终可能会发现使用C类型最容易表达hair.length,但是hair具有多个属性,并且可能需要实现或多态行为来表示hair作为一个对象,因此,作为更复杂的表示形式,使用类可能更适合,而长度可以使用int,颜色属性可以使用NSColor或UIColor。 - justin
但是许多 Objective-C 开发者在面向对象设计方面并没有充分利用 C 语言的优势,除非需要考虑性能或可移植性。他们只是在更容易以 Objective-C 类型(或集合等)表示某些内容时使用 Objective-C 类型。 - justin
我想在我的伪例子中保留“人”作为我的对象。所以即使我有3个人对象,它们都有一个“头发”属性。这确实是我能给出的最好的现实世界的例子,因为我只是推断想法。我思考的原因是,也许person1有一个遵循相同“头发”实体的“胡须”。person2.hair.color = brown; person1.beard.color = black; 我的最终目标是最有效和最简约的编码方法。我已经开始理解O-C,现在正在努力优化它。如果可以用一行代码完成,为什么要用10行呢? - DoS
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接