CGColorRef is NOT a struct

The documentation for CGColorRef (https://developer.apple.com/documentation/coregraphics/cgcolorref?language=objc) clearly shows that it is a struct. However, when I try to store a cell's border color using CGColorRef originalColor = self.bg.layer.borderColor and inspect what happens in the debugger, both that property and its copy have the same address. And later when I try to restore the border color the copy still has the same address but is no longer valid and causes a crash on assignment (originalColor is actually an instance variable...)

This is all object behavior, not struct behavior. If CGColorRef really was a struct, the contents would have been copied, the instance variable would have had its own address that would never have changed, and the value would have remained valid indefinitely and let me copy it back without a problem.

Why is this documented wrong? Was this a recent change? I actually had this code working at some point, and now it's broken.

Answered by endecotp in 852147022

2 years and 10 months later, this seems to have been fixed!

I'm not expert in objc, but struct in objc and Swift are very different beasts :

https://stackoverflow.com/questions/55213078/what-is-the-difference-between-swift-structs-and-objective-c-structs

https://robopress.robotsandpencils.com/understanding-reference-vs-value-types-in-objective-c-and-swift-5696845e8c9

AFAIU, struct in objc are in fact reference values as well.

Note that in Swift, CGColor is a class.

Accepted Answer

The documentation for CGColorRef (https://developer.apple.com/documentation/coregraphics/cgcolorref?language=objc) clearly shows that it is a struct. 

Right, that should surely say

typedef struct CGColor* CGColorRef;

The same issue seems to appear here:

https://developer.apple.com/documentation/coregraphics/cgcolorspaceref?language=objc https://developer.apple.com/documentation/coregraphics/cgcontextref?language=objc https://developer.apple.com/documentation/coregraphics/cgfontref?language=objc etc. etc.

Presumably this is something gone wrong with the tool that extracts the documentation from the header files.

File a bug?

CGColor* means you declare CGColorRef as a pointer to a CGColor struct. Hence a reference.

https://stackoverflow.com/questions/581689/what-does-the-asterisk-mean-in-objective-c

Sorry, I did not know your level of knowledge in objc (which may well be higher than mine !).

Your are right, I now see in doc

typedef struct CGColor CGColorRef;

However I'm quite sure I saw something different yesterday, as

typedef struct CGColor* CGColorRef;

Did they change it in the meantime or did I dream ?

This isn't fixed, after 3 months.

I'm just looking at another documentation bug which I reported in July 2022 (FB10566903) that hasn't been fixed.

Did the developer documentation team all get fired, or something?

Come on Apple. We need the documentation to be accurate. It's really difficult to write code when we can't be sure if the bug is in our code, your code, or your documentation.

2 years and 10 months later, this seems to have been fixed!

[quote='745841022, endecotp, /thread/719047?answerId=745841022#745841022, /profile/endecotp'] I'm just looking at another documentation bug which I reported in July 2022 FB1056690 [/quote]

That bug got very lost. I’m not actually sure what happened, but my best guess is that you filed it against a user-level component. I’ve taken steps to get it back on the right path.

It was easy to accidentally file a user-level bug bug in a user-level component [See the footnote at the end of this post.] back in the day, because the component list was a massive popup and all the developer-level components were sorted at the end. These days we have a top-level item, Developer Technologies & Resources, and if you’re a developer filing a code-level issue it’s always good to start there. I call this out in Bug Reporting: How and Why?.


Coming back to the original issue, FB11739379 definitely made it to the right place, although it wasn’t the driver for the fix reported by endecotp.

AgentFriday, I’d like to clarify your actual concern here. The page you referenced is the Objective-C documentation. The Swift equivalent says:

class CGColor

and I presume that’s OK by you.

Now, returning to the Objective-C doc, I see this:

typedef struct CGColor * CGColorRef;

Are you specifically complaining about the keyword struct in the above?

If so, I think you’re misreading this. That declaration actually defines two types:

  • struct CGColor, which is an incomplete C struct type
  • CGColorRef, which is a C pointer type

Strictly speaking neither type is an object, because this is a C header file and C doesn’t support objects.

This type is actually a CF-style type, which means it’s declared in C but has Objective-C like semantics. Many such types are bridged to Swift as Swift classes, and that’s exactly what happens here. However, it’s not the struct CGColor that’s bridged to Swift’s CGColor, but rather the CGColorRef is bridged to Swift, being renamed to CGColor along the way.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

Now, returning to the Objective-C doc, I see this:

What you're seeing now is the fixed version. Until yesterday, the * was missing. AgentFriday and I both understand the differences between classes and structs in C, objC and Swift and neither of us was misreading anything. There was no confusion; it was a bug in the documentation generator which has now finally been fixed.

user-level bug

Huh? There's a difference between "user-level bugs" and "developer-level bugs"? I guess I'd better go and look at all my completely ignored bug reports from the last decades and check if any of them accidentally got in a "user-level" category.

There's a difference between "user-level bugs" and "developer-level bugs"?

That’s not what I said [1]. Rather, I talked about user-level components and developer-level components.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

[1] Well, I said it in one of the three places. When I wrote “file a user-level bug” I was using that as a shorthand. I’ve now replaced that with “file a bug in a user-level component”, just to be clear.

CGColorRef is NOT a struct
 
 
Q