问题描述
我将简短地讲一个很长的故事,并举例说明我的问题。
I'll cut a really long story short and give an example of my problem.
给定一个具有指向基本类型作为属性的类的类:
Given a class that has a pointer to a primitive type as a property:
@interface ClassOne : NSObject
{
int* aNumber
}
@property int* aNumber;
该类被实例化,并且aNumber被分配并分配一个值,相应地:
The class is instantiated, and aNumber is allocated and assigned a value, accordingly:
ClassOne* bob = [[ClassOne alloc] init];
bob.aNumber = malloc(sizeof(int));
*bob.aNumber = 5;
然后通过引用传递它,以指定此类型的单独实例的aNumber值类,相应:
It is then passed, by reference, to assign the aNumber value of a seperate instance of this type of class, accordingly:
ClassOne* fred = [[ClassOne alloc] init];
fred.aNumber = bob.aNumber;
Fred的aNumber指针随后被释放,重新分配并分配一个新值,例如7。
Fred's aNumber pointer is then freed, reallocated, and assigned a new value, for example 7.
现在,我遇到的问题;
由于Fred已被赋予与Bob相同的指针,我希望Bob的aNumber现在的值为7.它没有,因为由于某种原因它的指针被释放,但没有重新分配(它是仍然指向它首先被分配的相同地址,现在已被释放。
然而,Fred的指针在不同的内存位置具有分配值7.
Now, the problem I'm having;Since Fred has been assigned the same pointer that Bob had, I would expect that Bob's aNumber will now have a value of 7. It doesn't, because for some reason it's pointer was freed, but not reassigned (it is still pointing to the same address it was first allocated which is now freed).Fred's pointer, however, has the allocated value 7 in a different memory location.
为什么它的行为如此?我有什么理解?我怎样才能让它像C ++一样工作?
Why is it behaving like this? What am I minsunderstanding? How can I make it work like C++ does?
编辑:
对,一个清晨,我可以看到我给了一个非常糟糕的,5pm综合症的例子。
我想要做的更像是这样:
Right, a fresh morning and I can see I gave a really bad, 5pm syndrome example.What I'm trying to do is more like this:
@interface classOne : NSObject
{
int* numA;
}
@property int* numA;
@implementation...etc
numA被分配并分配一个值。稍后,在一个单独的线程(有必要的锁等),这样做:
numA is alloced and assigned a value. Later on, in a seperate thread (with necessary locks etc), this is done:
int* numB= malloc(sizeof(int));
*numB = 5;
free(RefToClassOne.numA);
RefToClassOne.numA = numB;
numA确实被释放,但没有被赋予numB指向的值,这是我想要的行为。
numA does get freed, but does not get assigned the value that numB is pointing to, which is the behaviour I would like.
长篇故事的一部分是它是传递给openGL的顶点缓冲区的一部分的顶点数。我意识到它不应该是一个指针,但是坐标的float *缓冲区以相同的方式处理并且需要具有可变大小,所以我想解决这个问题以解决这个问题。
Part of the longer story is that it is the vertex count for part of a vertex buffer that is passed into openGL. I realise that it shouldn't be a pointer, but the float* buffer for the coordinates is dealt with in the same way and needs to be of variable size, so I want to fix this to solve that problem also.
推荐答案
你误解的是(a)你不能在Objective-C中通过引用传递东西,(b)即使你可以,它对你没有帮助。
What you are misunderstanding is that (a) you cannot pass things by reference in Objective-C, and (b) even if you could, it wouldn't help you here.
Objective-C只允许你按价值传递东西。有时,如对象或指针的情况,您传递的值是本身一个引用,但它被视为一个值。 C ++ - 样式透明引用不存在。
Objective-C only allows you to pass things by value. Sometimes, as in the case of objects or pointers, the value you are passing is itself a reference, but it's being treated as a value. C++-style transparent references don't exist.
但是假设我们有它们。在这种情况下,这会有什么帮助? aNumber
实例变量的类型仍为 int *
;当您分配给它时(如 fred.aNumber = bob.aNumber
),您必须创建一个副本。在这一点上,通过引用传递的内容并不重要,并且事物是实例变量也不重要。您的代码实际上与
But suppose that we had them. How would that help in this case? The aNumber
instance variable is still of type int*
; when you assign to it (as in fred.aNumber = bob.aNumber
), you must create a copy. At this point, it doesn't matter what was passed by reference, and nor does it matter that things are instance variables. Your code is effectively the same as
int* bobNumber;
int* fredNumber;
bobNumber = malloc(sizeof(int));
*bobNumber = 5;
fredNumber = bobNumber;
此处, bobNumber
和 fredNumber
是不同的变量—它们有不同的名称,存在于内存中的不同位置等等。—碰巧具有相同的值。现在,它们具有的值是对内存中另一个位置的引用,因此它们是等效的引用。但是,如果我们改变其中一个会发生什么?
Here, bobNumber
and fredNumber
are different variables—they have different names, live at different locations in memory, etc.—that happen to have the same value. Now, the value they have is a reference to another location in memory, so they are equivalent references. However, what happens if we change one of them?
free(fredNumber);
fredNumber = malloc(sizeof(int));
*fredNumber = 7;
由于函数参数是按值传递的,因此 free
无法对 fredNumber
本身做任何事情;它只能在 fredNumber
的值上运行,释放引用的内存。由于这与 bobNumber
的值相同,如果我们尝试取消引用 bobNumber
,我们会看到此效果。接下来,我们为 fredNumber
分配一个值。由于 fredNumber
和 bobNumber
生活在内存中的不同位置,因此该赋值对 bobNumber无效
。此时, fredNumber!= bobNumber
,当我们将 7
分配给 * fredNumber时自然如此
, * bobNumber
没有任何反应(无论如何,这是无效的,只是免费
d )。
Since function arguments are passed by value, free
can't do anything to fredNumber
itself; it can only operate on fredNumber
's value, freeing the referenced memory. Since this is the same as bobNumber
's value, we see this effect if we try to dereference bobNumber
. Next, we assign a value to fredNumber
. Since fredNumber
and bobNumber
live at different locations in memory, this assignment naturally does nothing to bobNumber
. At this point, fredNumber != bobNumber
, so naturally when we assign 7
to *fredNumber
, nothing happens to *bobNumber
(which is invalid anyway, having just been free
d).
请注意,关于让它像C ++一样工作的评论很奇怪;像我说的那样,C ++也不会这样。如果你真的想在C ++中使用它,你必须有一个引用实例变量
Note that your comment about "making it work like C++ does" is strange; C++, like I said, doesn't work this way either. If you really wanted to make this work in C++, you would have to have a reference instance variable
class ClassTwo {
public:
int*& aNumber;
ClassTwo(int*& an) : aNumber(an) { }
};
注意一个
需要通过参考;我原本试图在没有它的情况下做到这一点,然后在构造函数中创建了一个副本,产生了同样的旧问题。
Note that an
needs to be passed by reference; I originally tried to do it without that, and then a copy was created in the constructor, producing the same old set of problems.
现在,无论我们是否通过 bob
通过引用,它仍将具有相同的 aNumber
引用,因此我们可以构建类似
Now, whether or not we pass bob
by reference, it will still have the same aNumber
reference, so we can construct something like
int* shared;
ClassTwo bob(shared);
bob.aNumber = new int(5);
ClassTwo fred(bob.aNumber);
delete fred.aNumber;
fred.aNumber = new int(7);
一切都会像你期望的那样运作。但是,这可能不是一个好主意。出于一个原因,请注意共享
变量—引用需要能够引用某些内容。这会产生问题:如果被引用的对象超出范围,则引用的行为是未定义的。
And everything will work like you expect. However, this may well not be a good idea. For one reason why, note the shared
variable—references need to be able to reference something. And this can produce problems: if the object being reference goes out of scope, the behavior of the reference is undefined.
这篇关于Objective-C类,原始类型的指针等的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!