通过引用另一个 class 传递 CGFloat 的最佳方式

Best way to pass CGFloat by reference to another class

ClassA 中,我有一个 CGFloatx,我想通过引用传递给 ClassB,这样如果我对 [= ClassA中的14=],会体现在ClassB中对x的引用中。此外,当我将它传递给 ClassB 时,我想将其存储为 属性.

我考虑过使用 CGFloat 指针,但我正在努力找出使它成为 属性:

的正确语法
@property(nonatomic) CGFloat *x;

然后取消引用它:

self->x

我考虑过使用 NSNumber,但无法使用 NSNumber 设置值,使其在 ClassB 中更新。我考虑过放弃并制作一个包装器 class 来存储 CGFloat,但这似乎有点过分了。

执行此操作的最佳模式是什么?

[NSMutableData dataWithLength:sizeof(CGFloat)] 并将 mutableBytes 转换为 CGFloat*

您可以实现 属性 的 getter 和 setter @property(nonatomic) CGFloat x - 无需指针

I thought about giving up and making a wrapper class to store the CGFloat, but this seems like overkill.

这种方法的优点是安全,你创建一个对象,class都引用它,ARC 负责内存管理。

class容易定义,例如:

@interface ABShare1 : NSObject
@property CGFloat x;
@end

@implementation ABShare1
@end

(在 .h & .m 文件中——其他示例相同)

A class 使用它会是这样的:

@implementation ClassA
{
   ABShare1 *one;
}
...
one = ABShare1.new; // somewhere in initialisation
...
... one.x = 42; ... z = one.x * 24; ...

注意:上面将ABShare1引用存储在私有实例变量中,如果您愿意,可以将其存储在属性中,但没有必要。

您可以调用另一个 class 传递对象的方法,例如:

ClassB *myB;
...
[myB using:(ABShare1 *)sharedVariable];

并且其他 class 可以根据需要保留引用,内存管理是自动的。

I've thought about using a CGFloat pointer

这是"passing by reference"的标准C(Objective-C的子集)方式。

您可以将 CGFloat * 存储在 属性 中,Objective-C 中的所有 "object" 值属性仅存储指针(例如 @property NSString *name; 存储指向NSString 对象)。

您必须创建 CGFloat * 引用的变量,相当于 new 或 Objective-C 中的 alloc/init。您可以使用变量的地址,例如类似于:

CGFloat actualX;
CGFloat *x = &actualX;

但您必须手动确保引用的变量 actualX 至少与其存储在 x 中的指针在使用中一样长 - 否则会导致悬挂指针.

另一种选择是动态分配存储,直接相当于new,例如类似于:

CGFloat *x = malloc(sizeof(CGFloat));

但是,您现在负责确定何时不再需要存储并释放它(使用 free())。

您的第一个解决方案是 "overkill" – 可能是因为当您从对内存管理的担忧中解脱出来时,您不会得到 "variable" 而是两个 functions/methods 到 get/set一个值。

第二种解决方案最接近"variable",您只需使用*sharedVariable而不是sharedVariable。然而,虽然所需的手动内存管理是 C 程序员的标准配置,但它不适用于 Objective-C 程序员。

第三种方法将两种方法混合在一起,建立在如何使用 C 中的结构 (struct) 的基础上:共享一组变量而不是按地址单独共享每个变量,而是定义一个 struct 为每个变量分配一个成员,分配一个并共享其地址,例如:

typedef struct ABShare
{  CGFloat x;
   CGFloat y;
} ABShare;

ABShare *one = malloc(sizeof(ABShare));
one->x = 42;
one->y = 24;

以上与第二种解决方案存在相同的内存管理问题,但我们可以将其转换为非常接近的 Objective-C 等价物:

@interface ABShare : NSObject
{
@public // required
   CGFloat x;
   CGFloat y;
}
@end

@implementation ABShare
@end

注意:Objective-C classes 是使用 structs 有效实现的,实际上第一个 Objective-C 编译器实际上将它们翻译成 C struct代码.

使用这个非常接近C:

ABShare *one = ABShare.new;
one->x = 42;
one->y = 24;

与 C 相同 "variable",但具有自动内存管理。

最后一个方案本质上是 Objective-C 在创建块时管理共享变量的方式——块访问的所有局部变量都被移动到动态分配的 object/struct 中,然后使用->.

Objective-C 哪个最好?第一个和第三个都是 "Objective-C" 风格,第二个在与 C API 交互时通常避免接受。在第一个和第三个选择中,无论哪个感觉 "right" 在语义上,而不是对性能的关注,给你。 HTH