Get the address of an Objective-c property (which

2020-02-12 05:44发布

I have an Objective-C class which contains a C-style struct. I need to call a C function passing a pointer to this object member (a.k.a. property). For the life of me, I can't figure out how to get the address of this C struct. Using the traditional & operator to get the address, I'm getting an LValue compiler error.

typedef struct _myStruct
{
   int aNumber;
}MyStruct, *pMyStruct;

@interface MyClass : NSObject {
    MyStruct mystruct;
}
@property (readwrite) MyStruct myStruct;
@end

The following code results in a compiler error:

MyClass* myClass = [[MyClass alloc] init];

MyStruct* p = &(myClass.myStruct);

How do I get a pointer to the myStruct member of the myClass object?

4条回答
做个烂人
2楼-- · 2020-02-12 06:20

MyStruct mystruct is private in MyClass, I assume when you do myClass.myStruct you are only refering to generated accessor method not the actual structure.

I don't think you can access the instance variable (structure in this case) from outside because it is private.

查看更多
我想做一个坏孩纸
3楼-- · 2020-02-12 06:27

The question itself demostrates a lack of understanding of at least the terminology.

A property is an interface consisting of two (or one for readonly) methods made public by the object, namely the getter and setter methods, in this case:

- (MyStruct) myStruct;
- (void) setMyStruct: (MyStruct) newMyStruct;

It makes no sense to talk about "taking the address of a property".

You can take the address of an instance variable (ivar). In this case you have an ivar named mystruct, and you can take the address of it with &mystruct in a method of MyClass. Since it is marked @protected (by default), you can take the address of it in a subclass using &self->mystruct. If you mark it @public, then you could take the address of it using &myobj->mystruct. This is a terrible idea, and you should really really rethink this, but you could do it.

If you just want the address of the ivar for some short lived purpose (for example, if MyStruct was large) you could do this, but it would be very unusual, and you'd be better off writing an explicitly named method like:

- (MyStruct*) getAddressForSettingMyStruct;

and if it is just read only, even better would be to use const MyStruct*.

查看更多
唯我独甜
4楼-- · 2020-02-12 06:35

To get a pointer to the myStruct instance variable, you need to write a method that returns a pointer to that instance variable.

- (void)getMyStructPointer:(MyStruct **)outStruct {
    *outstruct = &myStruct;
}

I don't really think this is a good idea, though. Other objects should not be mutating that object's ivar out from under it, and that's the only thing you can do with a pointer to the struct that you can't do with a copy of the struct returned by value.

查看更多
神经病院院长
5楼-- · 2020-02-12 06:36

There are often pretty good reasons to do what the original post is asking, given that Objective-C apps often have to work with C/C++ API's that take pointers to structs and similar types, but in a Cocoa app you'll often want to store such data in Objective-C classes for data management, collection in arrays and dictionaries, etc.

Though this question has been up for awhile I don't see the clear answer, which is: you can have a method that returns the address of the data that's backing your property, but in that method don't use "self" or it will go through the accessor and still not work.

- (const MyStruct*) getMyStructPtr
{
    return &mystruct;
}

Note that I'm using the declared property from the OP, but not referencing it as self.mystruct, which would generate a compiler error (because that invokes the synthesized getter method).

查看更多
登录 后发表回答