Why doesn't objective-c allow pointers to a struct? - objective-c

I was wondering why objective-c (ARC) does not allow me to use a pointer to a struct (NSPoint, in this case)
My code works without one, I just want to question why it doesn't allow it as I have not found a reason on Google for it.
My current guess is because structs cannot contain objects, but I want to double check that; and want to know where the struct itself is saved. Thanks!

When migrating to ARC, the compiler no longer allowed this due to the complexity of how the struct containing object pointers would be initialized, copied, moved, or destroyed.
Apple called this out in the Transitioning to ARC guides line the "ARC Enforces New Rules" section.
You cannot use object pointers in C structures.
Rather than using a struct, you can create an Objective-C class to manage the data
instead.
However this is now allowed in LLVM as of this commit.
To quote directly from the commit message:
Declaring __strong pointer fields in structs was not allowed in
Objective-C ARC until now because that would make the struct
non-trivial to default-initialize, copy/move, and destroy, which is
not something C was designed to do. This patch lifts that restriction.
Special functions for non-trivial C structs are synthesized that are
needed to default-initialize, copy/move, and destroy the structs and
manage the ownership of the objects the __strong pointer fields point
to. Non-trivial structs passed to functions are destructed in the
callee function.

Related

Swift's Array type is bridged to Foundation's NSArray class, how?

In Swift Language Guide we read the following:
Swift’s Array type is bridged to Foundation’s NSArray class.
How can Swift's Array be bridged to Foundation's NSArray class when the first is a value type and the latter is a reference type? Doesn't bridging mean having an interface in a language to use a code in a different language?
The value/reference distinction here is a bit of a red herring.
Bridging is (maybe surprisingly) straightforward. There's an internal protocol, _ObjectiveCBridgeable, that describes a type which can be cast between an ObjC and a Swift type. The compiler replaces, e.g., your mySwiftArray as NSArray with a call to _bridgeToObjectiveC().
You can see Array's conformance to the protocol in Foundation. It's simple Swift code: each method just constructs an instance of the appropriate bridged type.
So there's not really any relation to the fact that the native Swift Array is a value type.
As for that piece; while externally a "value", Swift.Array actually has an internal pointer to its own storage. If you think about it for a second, this is the only sensible way to make it work. You don't want to be moving the 101 things in an array every time you assign it to a new variable. Just a nice quick copy of a pointer. (Of course you need to do the copy if you want to change something, but it's delayed as long as possible.)
You can see basically the same behavior in a C struct with a field that's a reference to some allocated memory:
typedef struct _Array {
void * payload;
} Array;
Array c;
c.payload = malloc( /* Whatever */ );
Array d = c;
Assigning to d makes a copy of the pointer to the storage, but there's only one chunk of allocated memory, which hasn't moved or been copied. (And to extend this backwards, you can "bridge" this to NSArray in the same way Swift.Array does: by providing an appropriate function that does the transformation.)
We can reason how this is might be supported without watching a video, though do that as well!
Doesn't bridging mean having an interface in a language to use a code in a different language?
Well a bridge in general is just a means of connection...
How can Swift's Array be bridged to Foundation's NSArray class when the first is a value type and the latter is a reference type?
... which doesn't preclude conversion as part of the process.
To subclass an NSArray just requires overriding two methods count and objectAtIndex:. To bridge a Swift array to an Objective-C one a subclass of NSArray can be defined which contains (a copy of) the Swift array, i.e. stored in an instance variable.
This subclass would implement the two required Objective-C methods in terms of the corresponding methods on the wrapped Swift array, doing any additional processing necessary; e.g. during indexing to wrap a Swift value as an opaque Objective-C object or convert it to a corresponding Objective-C object. Such a process would be "lazy", individual elements in the Swift array only being converted to Objective-C objects when, and if, they are accessed. Once converted values can be cached to avoid re-conversion.
The actual implementation will be optimised and probably take advantage of private information. However as the above shows there is nothing to prevent a bridge presenting a value type in Swift as a reference type in Objective-C, and vice-versa.
HTH

ARC - why do object pointers require explicit ownership type in function definitions?

void testFunction (id testArgument[]) {
return;
}
I'm getting the error "Must explicitly describe intended ownership of an object array parameter". Why does ARC need me to specify the ownership type of the objects in the testArgument array?
To expand on Jeremy's answer, ARC had two primary goals when designed:
make memory management as fully automatic as possible in pure Objective-C code while also preserving or maximizing efficiency (in fact, ARC can be more efficient than manual retain release).
require exactly specific declaration of memory management intent when crossing the boundary between C and Objective-C.
As well, the implementation of ARC is extremely conservative. That is, anywhere where the behavior has traditionally been "undefined", ARC will spew a warning.
Thus, in this case, the declaration of intent is required so that the compiler can apply a consistent and specific set of memory management rules to the contents of the array.
Because ARC needs to know whether to insert retain/release calls for you to avoid memory leaks.

objective-c memory management--how long is object guaranteed to exist?

I have ARC code of the following form:
NSMutableData* someData = [NSMutableData dataWithLength:123];
...
CTRunGetGlyphs(run, CGRangeMake(0, 0), someData.mutableBytes);
...
const CGGlyph *glyphs = [someData mutableBytes];
...
...followed by code that reads memory from glyphs but does nothing with someData, which isn't referenced anymore. Note that CGGlyph is not an object type but an unsigned integer.
Do I have to worry that the memory in someData might get freed before I am done with glyphs (which is actually just pointing insidesomeData)?
All this code is WITHIN the same scope (i.e., a single selector), and glyphs and someData both fall out of scope at the same time.
PS In an earlier draft of this question I referred to 'garbage collection', which didn't really apply to my project. That's why some answers below give it equal treatment with what happens under ARC.
You are potentially in trouble whether you use GC or, as others have recommended instead, ARC. What you are dealing with is an internal pointer which is not considered an owning reference in either GC or ARC in general - unless the implementation has special-cased NSData. Without that owning reference either GC or ARC might remove the object. The problem you face is peculiar to internal pointers.
As you describe your situation the safest thing to do is to hang onto the real reference. You could do this by assigning the NSData reference to either an instance variable or a static (method local if you wish) variable and then assigning nil to that variable when you've done with the internal pointer. In the case of static be careful about concurrency!
In practice your code will probably work in both GC and ARC, probably more likely in ARC, but either could conceivably bite you especially as compilers change. For the cost of one variable declaration and one extra assignment you avoid the problem, cheap insurance.
[See this discussion as an example of short lifetime under ARC.]
Under actual, real garbage collection that code is potentially a problem. Objects may be released as soon as there is no longer any reference to them and the compiler may discard the reference at any time if you never use it again. For optimisation purposes scope is just a way of putting an upper limit on that sort of thing, not a way of dictating it absolutely.
You can use NSAllocateCollectable to attach lifecycle calculation to C primitive pointers, though it's messy and slightly convoluted.
Garbage collection was never implemented in iOS and is now deprecated on the Mac (as referenced at the very bottom of this FAQ), in both cases in favour of automatic reference counting (ARC). ARC adds retains and releases where it can see that they're implicitly needed. Sadly it can perform some neat tricks that weren't previously possible, such as retrieving objects from the autorelease pool if they've been used as return results. So that has the same net effect as the garbage collection approach — the object may be released at any point after the final reference to it vanishes.
A workaround would be to create a class like:
#interface PFDoNothing
+ (void)doNothingWith:(id)object;
#end
Which is implemented to do nothing. Post your autoreleased object to it after you've finished using the internal memory. Objective-C's dynamic dispatch means that it isn't safe for the compiler to optimise the call away — it has no way of knowing you (or the KVO mechanisms or whatever other actor) haven't done something like a method swizzle at runtime.
EDIT: NSData being a special case because it offers direct C-level access to object-held memory, it's not difficult to find explicit discussions of the GC situation at least. See this thread on Cocoabuilder for a pretty good one though the same caveat as above applies, i.e. garbage collection is deprecated and automatic reference counting acts differently.
The following is a generic answer that does not necessarily reflect Objective-C GC support. However, various GC implementaitons, including ref-counting, can be thought of in terms of Reachability, quirks aside.
In a GC language, an object is guaranteed to exist as long as it is Strongly-Reachable; the "roots" of these Strong-Reachability graphs can vary by language and executing environment. The exact meaning of "Strongly" also varies, but generally means that the edges are Strong-References. (In a manual ref-counting scenario each edge can be thought of as an unmatched "retain" from a given "owner".)
C# on the CLR/.NET is one such implementation where a variable can remain in scope and yet not function as a "root" for a reachability-graph. See the Systems.Timer.Timer class and look for GC.KeepAlive:
If the timer is declared in a long-running method, use KeepAlive to prevent garbage collection from occurring [on the timer object] before the method ends.
As of summer 2012, things are in the process of change for Apple objects that return inner pointers of non-object type. In the release notes for Mountain Lion, Apple says:
NS_RETURNS_INNER_POINTER
Methods which return pointers (other than Objective C object type)
have been decorated with the clang compiler attribute
objc_returns_inner_pointer (when compiling with clang) to prevent the
compiler from aggressively releasing the receiver expression of those
messages, which no longer appear to be referenced, while the returned
pointer may still be in use.
Inspection of the NSData.h header file shows that this also applies from iOS 6 onward.
Also note that NS_RETURNS_INNER_POINTER is defined as __attribute__((objc_returns_inner_pointer)) in the clang specification, which makes it such that
the object's lifetime will be extended until at least the earliest of:
the last use of the returned pointer, or any pointer derived from it,
in the calling function;
or the autorelease pool is restored to a
previous state.
Caveats:
If you're using anything older then Mountain Lion or iOS 6 you will still need to use any of the methods discussed here (e.g., __attribute__((objc_precise_lifetime))) when declaring your local NSData or NSMutableData objects.
Also, even with the newest compiler and Apple libraries, if you use older or third party libraries with objects that do not decorate their inner-pointer-returning methods with __attribute__((objc_returns_inner_pointer)) you will need to decorate your local variables declarations of such objects with __attribute__((objc_precise_lifetime)) or use one of the other methods discussed in the answers.

How are Objective-C objects protected?

In my previous question, I figured out that all Objective-C objects are declared as pointers. But in C and C++, pointers can be accessed from any function, global or not, and they seem unprotected.
How are they "protected" in Objective-C ?
ObjC does not police your use of pointers.
There is type checking at compile time, so if you have a pointer to an NSNumber, and use the variable that holds it to assign to an NSString, the compiler will issue a warning. However, this is easily overridden by casting the pointer, as shown below,
NSNumber *myNumberPtr = [NSNumber initWithInt:99];
NSString *myStringPtr = (NSString *) myNumberPtr;
In this case, the compiler is told to keep quiet, but accessing myStringPtr as a string would cause 'undefined results', hopefully something obvious like a crash, but possibly something more pernicious.
Similarly, I could declare,
NSString *notActuallyAString = 0x897996789; // assigned some random value
Then when notActuallyAString is accessed at runtime, it is highy likely to cause a bad access exception as the pointer is almost certainly not pointing to an NSString, and quite possibly isn't a valid memory address at all.
This makes C (and its associated languages) powerful for low-level programming (if you actually know the memory mapped address of some hardware register, you can assign them in this way, and access hardware), but brings pretty clear risks.
It gets worse, because you may have a valid pointer at some point in the execution, but the memory that the pointer references is freed off at some later point. Then if you (wrongly) access that pointer, you again may well get an exception as the memory is no longer valid for the purpose the code assumes. Writing (assigning) a via a pointer that pointers somewhere it shouldn't is a common cause of memory corruption, which can be a devil to diagnose. For this reason, it's good practice (aka defensive coding) to make sure pointers that you've finished with are assigned to nil, so if you reuse those pointers when you shouldn't, you should get a symptom that is more easy to diagnose than some random memory corruption.
You need a good understanding of pointers to program in objC, and I would recommend reading the timeless classic reference book, 'The C Programming Language' by Kernighan & Ritchie which explains the basics of pointers, you can then build your understanding on how pointers and memory allocation is used in ObjC and C++.
A pointer, per se, does not have any kind of protection.
You should take a look to some basics of OOP; members can be of three types: public, protected or private. This is what decides if you can access the member from outside the implementation of the class itself (not considering, of course, some kind of hacking like accessing private members modifying directly the bytes of the object. You must not, however, do something like this because it's strongly against the OO philosophy: if a member is private there is a reason, and forcing the access to it will not give you any guarantee that your code will work with future versions of the library or in other machines).
In Objective-C members are protected by default. That's what give the protection you are looking for.
In Objective-C, instance variables are not exposed by default. In Objective-C 2.0, they are exposed by properties using the #property and #synthesize syntax. (Prior to 2.0, solely by explicitly written getter/setter methods.)
That notwithstanding, it is possible to access instance variables directly using the pointer operator syntax, e.g. NSString *bar = Foo->_text; even when text is not exposed as a property.
Further, you can now declare instance variables in your implementation file, to avoid having them exposed in public header files. If you are writing framework code, this offers some 'protection' against access to ivars outside of the property accessors since they are no longer visible.

Objective-c: Objects by value / Structs with methods / How can I get something like that?

I'm starting to code in objective-c and I've just realized that objects can only be passed by reference.
What if I need an object to use static memory by default and to be copied instead of referenced?
For example, I have an object Color with 3 int components r, g and b. I dont want these objects to be in dynamic memory and referenced when passing to functions, I want them immutable and to be copied like an int or a float.
I know I can use a c struct, but I also need the object Color to have methods that gets/sets lightness, hue, saturation, etc. I want my code to be object oriented.
Is there any solution to this?
EDIT: If for example I'm building a 3d game engine, where I'll have classes like Vector2, Vector3, Matrix, Ray, Color, etc: 1) I need them to be mutable. 2) The size of the objects is roughly the same size of a pointer, so why would I be copying pointers when I can copy the object? It would be simpler, more efficient, and I wouldnt need to manage memory, specially on methods that returns colors. And In the case of a game engine, efficiency is critical.
So, if there is no solution to this... Should I use c-structs and use c-function to work on them? Isn't there a better choice?
Thanks.
You can't do this. This isn't how Objective-C works (at least the Apple/GNU version*). It simply isn't designed for that sort of extreme low-level efficiency. Objects are allocated in dynamic memory and their lifetimes are controlled by methods you call on them, and that's just how it works. If you want more low-level efficiency, you can either use plain C structs or C++. But keep in mind that worrying about this is pointless in 99% of circumstances — the epitome of premature optimization. Objective-C programs are generally very competitive with C++ equivalents both in execution speed and memory use despite this minor inefficiency. I wouldn't go for a more difficult solution until profiling had proved it to be necessary.
Also, when you're new to Objective-C, it's easy to psych yourself out over memory management. In a normal Cocoa (Touch) program, you shouldn't need to bother about it too much. Return autoreleased objects from methods, use setters to assign objects you want to keep around.
*Note: There was an old implementation of Objective-C called the Portable Object Compiler that did have this ability, but it's unrelated to and incompatible with the Objective-C used on Macs and iOS devices. Also, the Apple Objective-C runtime includes special support for Blocks to be allocated on the stack, which is why you must copy them (copy reproduces the block in dynamic memory like a normal object) if you want to store them.
What if I need an object to use static memory by default and to be copied instead of referenced?
You don't.
Seriously. You never need an object to use static memory or be allocated on the stack. C++ allows you to do it, but no other object oriented language I know does.
For example, I have an object Color with 3 int components r, g and b. I dont want these objects to be in dynamic memory and referenced when passing to functions, I want them immutable and to be copied like an int or a float.
Why do you not want the objects to be in static memory? What advantage do you think that gives you?
On the other hand it's easy to make Objective-C objects immutable. Just make the instance variables private and don't provide any methods that can change them once the object is initialised. This is exactly how the built in immutable classes work e.g. NSArray, NSString.
One solution that people use sometimes is to use a singleton object (assuming you only need one of the objects for your entire app's lifetime). In that case, you define a class method on the class and have it return an object that it creates once when it is first requested. So you can do something like:
#implementation MyObject
+ (MyObject *)sharedObjectInstance
{
static MyObject *theObject=nil;
if (theObject==nil)
{
theObject = [[MyObject alloc] init];
}
return theObject;
}
#end
Of course the object itself isn't what's being statically allocated, it's the pointer to the object that's statically allocated, but in any case the object will stick around until the application terminates.
There are times when you want to do this because you really only want one globally shared instance of a particular object. However, if that's not your objective, I'm not sure why you'd want to do what you're describing. You can always use the -copy method to create a copy of an object (assuming the object conforms to the NSCopying protocol) to manipulate without touching the original.
EDIT: Based on your comments above it seems you just want to have immutable objects that you can copy and modify the copies. So using -copy is probably the way to go.