Retain information in cocoa? - cocoa

I'm still new to Cocoa and don't know much about memory management. I read up on Apple's documentation but I'm still confused. My question is if I set the value of a variable in a - (void)dowhatever when dowhatever ends, will the contents of the variable be erased? If so is there a method (without writing to a file) that I can use to retain the variable contents?
Thanks for any help

My question is if I set the value of a variable in a - (void)dowhatever when the void ends, …
void is a type. It has no beginning and no end.
Specifically, it's the return type of the dowhatever method. If dowhatever returned a value, the type of that return value would be where you have void; it would say, for example, - (NSUInteger) doWhatever. Having void there means that the method does not return a value.
See also the Objective-C 2.0 Programming Language document.
… will the contents of the variable be erased?
If it's a local variable, then the variable will cease to exist when the method returns.
An instance variable exists as long as the instance (object) that the variable is a part of exists—that is, until the instance is deallocated.
Instance variables are also covered in the Objective-C documentation.
If so is there a method (without writing to a file) that I can use to retain the variable contents?
If you simply need to return the object to your caller, retain it and autorelease it. See the Memory Management Programming Guide for Cocoa for more info.
If that's not what you're doing, then the question becomes why you need the object to stay alive.
Think in terms of objects: An object may own certain other objects, and has an instance variable for every object it owns*. As long as you have your ownerships straight and uphold them in code, objects' lifetimes just work.
If object A needs another object B, then A should own B. This ownership isn't exclusive; it can co-own B. But it needs to at least co-own B; B will remain alive as long as it has at least one owner.
That's also covered in the Memory Management Guide. For other examples of relationships between objects, you should flip through the Cocoa Fundamentals Guide, particularly the chapter on Cocoa's design patterns, and you may want to look through sample code to see those patterns demonstrated in practice.
*It can also have instance variables for objects it doesn't own, such as delegates. You can have an instance variable for an object you don't own, but if you do own it, you should have an instance variable for it.

Related

Wrapping instance variables in accessor methods

Sandy Metz says (POODR book, page 26):
Because it is possible to wrap every instance variable in a method and to therefore treat any variable as if it's just another object, the distinction between data and a regular object begins to disappear.
I am not sure if I understand what she is explaining. When we define the accessors, we are wrapping the instance variables (data) on a method but methods are not objects. So what does she mean when she says that we can treat variables as if they're just another object?
The primary difference between data and objects is behaviour. Objects can modify their internal state without changing their interfaces, while data are static structures.
When we wrap data access within a method, we get the same benefits of an object - the interface remains static to consumers even if the underlying data structure needs to change.

Deleting an instance of a class via a method of that class

I have a class for pieces on a board. I want to be able to delete an instance of Piece so that anything else in the program that points to that piece will just point to nil.
Here's the very basic code version of what I want to do:
piece = Piece.new
variable = piece
variable #=> <Piece:0x0000000xxxxxxxx>
piece.delete
variable #=> nil
This seems like a very basic task so I feel like I'm missing something obvious. I've tried creating a delete method for the class with "self = nil", but this returns an error ("Can't change the value of self").
So far I have just worked around this by updating the other things that point to the object in my 'delete' method, but it seems like there should be a better way.
This is not possible.
Firstly, Ruby is an object-oriented language, which means that all manipulation is done via messages to objects, and all that is manipulated are objects. Variables are not objects, therefore you cannot manipulate them. (The only things you can do with variables are assign a value to them and dereference them.)
And even if you could manipulate variables, you would still need to hunt down every single reference to the object in question and remove it, in order for the object to be eligible for "deletion" (i.e. garbage collection).

Ruby: marshal and unmarshal a variable, not an instance

OK, Ruby gurus, this is a hard one to describe in the title, so bear with me for this explanation:
I'm looking to pass a string that represents a variable: not an instance, not the collection of properties that make up an object, but the actual variable: the handle to the object.
The reason for this is that I am dealing with resources that can be located on the filesystem, on the network, or in-memory. I want to create URI handler that can handle each of these in a consistent manner, so I can have schemes like eg.
file://
http://
ftp://
inmemory://
you get the idea. It's the last one that I'm trying to figure out: is there some way to get a string representation of a reference to an object in Ruby, and then use that string to create a new reference? I'm truly interested in marshalling the reference, not the object. Ideally there would be something like taking Object#object_id, which is easy enough to get, and using it to create a new variable elsewhere that refers to the same object. I'm aware that this could be really fragile and so is an unusual use case: it only works within one Ruby process for as long as there is an existing variable to keep the object from being garbage collected, but those are both true for the inmemory scheme I'm developing.
The only alternatives I can think of are:
marshal the whole object and cram it into the URI, but that won't work because the data in the object is an image buffer - very large
Create a global or singleton purgatory area to store a variable for retrieval later using e.g. a hash of object_id:variable pairs. This is a bit smelly, but would work.
Any other thoughts, StackOverflowers?
There's ObjectSpace._id2ref :
f = Foo.new #=> #<Foo:0x10036c9b8>
f.object_id #=> 2149278940
ObjectSpace._id2ref(2149278940) #=> #<Foo:0x10036c9b8>
In addition to the caveats about garbage collection ObjectSpace carries a large performance penalty in jruby (so much so that it's disabled by default)
Variables aren't objects in Ruby. You not only cannot marshal/unmarshal them, you can't do anything with them. You can only do something with objects, which variables aren't.
(It would be really nice if they were objects, though!)
You could look into MagLev which is an alternative Ruby implementation built on top of VMware's Gemstone. It has a distributes object model wiht might suit your use-case.
Objects are saved in the central Gemstne instance (with some nifty caching) and can be accessed by any number of remote worker instances. That way, any of the workers act on the same object space and can access the very same objects simultaneously. That way, you can even do things like having the global Garbage Collector running on a single Ruby instance or seamlessly moving execution at any point to different nodes (while preserving all the stack frames) using Continuations.

How does KVC in Cocoa check whether an instance variable is accessable?

Recently i was reading "Cocoa Design Patterns". When talking about KVC, it said "KVC check if an accessor named -<key> or -get<Key> exists first, if not, it will try instance variable named <key> or _<key>".
Can obj-c runtime check whether an instance variable exist? I think it can only be done in compile time...
Any answers are appreciated ^_^
It can indeed. The relevant documentation for this is the Objective-C Runtime Reference; specifically, class_getInstanceVariable. The part the documentation leaves out is that that function returns NULL when instances of the class have no such variable.
KVC, presumably, passes the object's class and the candidate variable names to that function, and the first name for which the runtime comes up with an Ivar is the one it uses.

State of object after std::move construction

Is it legal/proper c++0x to leave an object moved for the purpose of move-construction in a state that can only be destroyed? For instance:
class move_constructible {...};
int main()
{
move_constructible x;
move_constructible y(std::move(x));
// From now on, x can only be destroyed. Any other method will result
// in a fatal error.
}
For the record, I'm trying to wrap in a c++ class a c struct with a pointer member which is always supposed to be pointing to some allocated memory area. All the c library API relies on this assumption. But this requirement prevents to write a truly cheap move constructor, since in order for x to remain a valid object after the move it will need its own allocated memory area. I've written the destructor in such a way that it will first check for NULL pointer before calling the corresponding cleanup function from the c API, so that at least the struct can be safely destroyed after the move.
Yes, the language allows this. In fact it was one of the purposes of move semantics. It is however your responsibility to ensure that no other methods get called and/or provide proper diagnostics. Note, usually you can also use at least the assignment operator to "revive" your variable, such as in the classical example of swapping two values.
See also this question

Resources