通过引用另一个 class 传递 CGFloat 的最佳方式
Best way to pass CGFloat by reference to another class
在 ClassA
中,我有一个 CGFloat
值 x
,我想通过引用传递给 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 是使用 struct
s 有效实现的,实际上第一个 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
在 ClassA
中,我有一个 CGFloat
值 x
,我想通过引用传递给 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 是使用 struct
s 有效实现的,实际上第一个 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