Using Pointers safely in Objective-C - objective-c

Lets say I have an object with an integer instance variables and 1 member function. The function runs on a separate thread, and consistently updates the value of the instance variable. I have a second function (part of a different class) that also runs on a separate thread, and needs real time access to the integer instance variable in the first object. Therefore, I pass in a pointer to the instance variable to the second function and the second function just dereferences the pointer. This way the second function always has access to the updated value of the instance variable.
However, I do not want the second function to be able to change the value of the instance variable. I want it to have read-only access, but since I am passing in a pointer to the instance variable, will it be able to change the value of the instance variable? If so, how do I restrict pointer dereferencing to read only? If this isn't possible, what would be the safest solution to this problem?
Mac OS X Snowleopard, Xcode 3.2.6. Objective-C with Cocoa.
EDIT: Sorry I forgot to mention that I can't make the instance variable constant, because I need the class it belongs to to be able to modify it. If I make it constant, it would completely restricting writing to the variable.

You can use the type system here. Instead of having something like int* you can have const int *, which means it's a pointer to a constant int. It's possible to get around this by casting back to (int *) inside the function, but this is a violation of the type system (hence the explicit cast) and well-behaved functions won't do that.
Note, you may also need to throw in volatile if your function needs to make sure it has the up-to-date value. Otherwise the compiler may decide it's ok to cache the results of the dereference somewhere.

The right way to do this is make the instance variable a property, and to give the second function a pointer to the object instead of a pointer to the instance variable. The code can then call the object's accessor for the property. It's not clear how your code is structured, but it's also possible to make the property read-only for method outside the class definition, and read-write for methods that are part of the class.
Finally, since you're accessing the property from more than one thread, you'll need to provide some sort of synchronization to avoid having both threads try to access the property at the same time. The simplest way to do that is to omit 'nonatomic' (which is how most people reflexively declare their properties) from the property declaration, which will cause the property accessors to be atomic. The second simplest way is to use the #synchronized directive.

Related

objective-C instance variable to keep track of first time

I need to do an operation just once when my app is launched the first time. I fit success no need to repeat during subsequent launches.
I am using the standard approach of using a property and setting it to YES the first time app is launched and initialization code succeeds.
I have a few Qs that will help me improve my Objective-C understanding and hence would greatly appreciate the experts inputs.
I am assuming I need to set the property attribute to strong since the memory associated with the variable may be released if it is set to weak. Is this correct?
Setting it to strong is preventing me from using BOOL type (the error indicated I need to use an object)
To workaround, the property type is set to NSNumber and I am setting it to #(YES) after routine completes and comparing it against #(YES) to see if initialization needs to be done at app launch.
IS the above approach/understanding correct? If no, I'd appreciate pointers to what is wrong. Also, even if above will work, but there is a more elegant way to do what I'm trying to do, please do let me know.
I am assuming I need to set the property attribute to strong since the memory associated with the variable may be released if it is set to weak. Is this correct?
Sorry, NO.
An automatic property (one where you do not write your own setter and getter methods) lifetime & memory behaviour is the same as for instance variables. So:
The lifetime of the property is the same as the object instance it belongs to - the storage for the property is created as part of creating the object instance, and it is destroyed as part of destroying the instance.
For properties with primitive type; e.g. int, double, BOOL, NSInteger etc.; the value is stored directly in the property and there is no other memory management required.
For properties of object reference type; e.g. NSArray *, NSNumber *, etc.; the value stored in the property is a reference to an object. In this case the property may be marked as strong, weak, etc. so that ARC knows how to manage the lifetime of the referenced object (not the lifetime of the property).
So in your case with a BOOL property you do not need strong, weak, etc. - they would be meaningless for such a property. You do not convert your property to NSNumber * just so you can make it strong, there is no need to do this.
I am using the standard approach of using a property and setting it to YES the first time app is launched and initialization code succeeds
For your particular application this is not the standard approach, what you need is a value which will persist between application launches, and for that you can user NSUserDefaults. In particular you need the methods boolForKey: to retrieve the current value, and setBool:forKey: to set the value.
When you first run your application you will (obviously!) not yet have written any value to NSUserDefaults. In this situation, where a value for a key has not yet been written, the method boolForKey: will return NO. So all your application needs to do to run code once on the first run is to read the key you will use for this, say #"firstRunDone", and if the result is NO to execute the first-run code and then set the key value to YES.
HTH
You're right about using strong modifier. strong only applies to NSObject-derived types (ie types derived from NSObject, which implies it has to be a class type), so you are correct about using NSNumber instead of BOOL.
However, if you need to run only the first time the app launches, you need to store it in a more persitent place, e.g. NSUserDefaults; an ivar/property will be gone as soon as the app is terminated, and takes default value when the app launches again. NSUserDefaults also supports primitive BOOL type, no need to worry about memory policy.
The strong and weak property attributes are to do with Automatic Reference Counting within Objective-C, i.e., iOS uses this to know when an object is still being used and should be kept in memory. The "strong" attribute will increment the reference count of the object in question, preventing the memory associated with the variable being released; so yes you are correct when you say that you need to set the property to strong.
With weak properties, the referenced object may be released while the property holds the reference. This is a helpful explanation of memory leaks & properties etc: http://www.quora.com/What-is-the-difference-between-strong-retain-nonatomic-etc-in-the-Objective-C-iOS-property
To use the BOOL type, you do indeed need to use an object. BOOL is an intrinsic type and so cannot have an explicit value; there needs to be something there to be true or false (or yes or no, in this case).
I hope this has helped your understanding a bit :) There are other similar SO posts dealing with BOOL properties; they might be helpful too. Good luck!

Objective C++ block semantics

Consider the following C++ method:
class Worker{
....
private Node *node
};
void Worker::Work()
{
NSBlockOperation *op=[NSBlockOperation blockOperationWithBlock: ^{
Tool hammer(node);
hammer.Use();
}];
....
}
What, exactly, does the block capture when it captures "node"? The language specification for blocks, http://clang.llvm.org/docs/BlockLanguageSpec.html, is clear for other cases:
Variables used within the scope of the compound statement are bound to the Block in the normal manner with the exception of those in automatic (stack) storage. Thus one may access functions and global variables as one would expect, as well as static local variables. [testme]
Local automatic (stack) variables referenced within the compound statement of a Block are imported and captured by the Block as const copies.
But here, do we capture the current value of this? A copy of this using Worker’s copy constructor? Or a reference to the place where node is stored?
In particular, suppose we say
{
Worker fred(someNode);
fred.Work();
}
The object fred may not exist any more when the block gets run. What is the value of node? (Assume that the underlying Node objects live forever, but Workers come and go.)
If instead we wrote
void Worker::Work()
{
Node *myNode=node;
NSBlockOperation *op=[NSBlockOperation blockOperationWithBlock: ^{
Tool hammer(myNode);
hammer.Use();
}];
....
}
is the outcome different?
According to this page:
In general you can use C++ objects within a block. Within a member
function, references to member variables and functions are via an
implicitly imported this pointer and thus appear mutable. There are
two considerations that apply if a block is copied:
If you have a __block storage class for what would have been a
stack-based C++ object, then the usual copy constructor is used.
If
you use any other C++ stack-based object from within a block, it must
have a const copy constructor. The C++ object is then copied using
that constructor.
Empirically, I observe that it const copies the this pointer into the block. If the C++ instance pointed to by this is no longer at that address when the block executes (for instance, if the Worker instance on which Worker::Work() is called was stack-allocated on a higher frame), then you will get an EXC_BAD_ACCESS or worse (i.e. pointer aliasing). So it appears that:
It is capturing this, not copying instance variables by value.
Nothing is being done to keep the object pointed to by this alive.
Alternately, if I reference a locally stack-allocated (i.e. declared in this stack frame/scope) C++ object, I observe that its copy constructor gets called when it is initially captured by the block, and then again whenever the block is copied (for instance, by the operation queue when you enqueue the operation.)
To address your questions specifically:
But here, do we capture the current value of this? A copy of this using Worker’s copy constructor? Or a reference to the place where node is stored?
We capture this. Consider it a const-copy of an intptr_t if that helps.
The object fred may not exist any more when the block gets run. What is the value of node? (Assume that the underlying Node objects live forever, but Workers come and go.)
In this case, this has been captured by-value and node is effectively a pointer with the value this + <offset of node in Worker> but since the Worker instance is gone, it's effectively a garbage pointer.
I would infer no magic or other behavior other than exactly what's described in those docs.
In C++, when you write an instance variable node, without explicitly writing something->node, it is implicitly this->node. (Similar to how in Objective-C, if you write an instance variable node, without explicitly writing something->node, it is implicitly self->node.)
So the variable which is being used is this, and it is this that is captured. (Technically this is described in the standard as a separate expression type of its own, not a variable; but for all intents and purposes it acts as an implicit local variable of type Worker *const.) As with all non-__block variables, capturing it makes a const copy of this.
Blocks have memory management semantics when they capture a variable of Objective-C object pointer type. However, this does not have Objective-C object pointer type, so nothing is done with it in terms of memory management. (There is nothing that can be done in terms of C++ memory management anyway.) So yes, the C++ object pointed to by this could be invalid by the time the block runs.

If blocks are objects, how do they keep internal state and what are their advantages over regular objects?

I was under the impression that blocks were supposed to resemble first-class functions and allow for lambda calc-style constructs. From a previous question however, I was told they are actually just objects.
Then I have 2 questions really:
Besides the feature of having access to their defining scope, which
I guess makes them usable in a way resembling C++ "friendship", why
would one go for a block instead of an object then? Are they more
lightweight? Because if not I might as well keep passing objects as
parameters instead of blocks.
Do blocks have a way of keeping an internal state? for instance,
some variable declared inside the block which will retain its value
across invocations.
Besides the feature of having access to their defining scope, which I guess makes them usable in a way resembling C++ "friendship", why would one go for a block instead of an object then?
Flexibility. Less to implement. A block is able to represent more than a parameter list or specific object type.
Are they more lightweight?
Not necessarily. Just consider them another tool in the toolbox, and use them where appropriate (or required).
Do blocks have a way of keeping an internal state? for instance, some variable declared inside the block which will retain its value across invocations.
Yes, they are able to perform reference counting as well as copy stack objects. That doesn't necessarily make them lighter-weight to use than an object representing the parameters you need.
Related
What's the difference between NSInvocation and block?
blocks were supposed to resemble first-class functions [...] they are actually just objects.
They are in fact first-class functions, implemented for the purposes of ObjC as objects. In plain-C, where they are also available, they have a closely-related but non-object-based implementation. You can think about them in whichever way is most convenient at the moment.
why would one go for a block instead of an object then?
A block is an executable chunk of code which automatically captures variables from its enclosing scope. The state and actions of a custom object have to be more explicitly handled, and are less generic; you can't use any old object as a completion argument, whereas an executable object fits that bill perfectly.
Do blocks have a way of keeping an internal state? for instance, some variable declared inside the block which will retain its value across invocations.
Sure, you can declare a static variable just like you could with a function or method:
void (^albatross)(void);
albatross = ^{
static int notoriety;
NSLog(#"%d", notoriety++);
};
albatross();
albatross();
albatross();
albatross();

Is it OK to access instance variables directly in an instance method of the same class to read their value?

I have an instance variable -> mXYZ
I have read at many places that its better to have accessors for these methods.
But if I am only using them inside the class and that too for reading.
I know that to modify a instance var, we should always use a setter as there is some work to be done like releasing old object being pointed to and few other things.
But getters just simply return what the instance variable is, Then is it necessary that I use a getter to access it within the class ?
the variable is not be accessed outside the class.
Although you are probably right that getters usually just return the value, the same logic applies to them as to the setters. That is to say, it is possible that the getter is doing some important extra work that you would bypass if you tried to access the variable directly.
For example, a class might defer loading the values of some of its properties (i.e. ivar values) from disk or a remote server until one of them is accessed via its getter.
If you have a private instance variable in your class then whether to just access it directly or define a property depends on:
how you use it: do you need to manage (de)allocation, do you wish to delay delay creation, it is a pseudo-variable (e.g. storing temp in F but having both F and C properties)
the type of memory management you use: manual (retain/release) or automatic (ARC or garbage collection)
Properties are usually of little benefit for primitive-typed variables, pseudo-variables being an obvious counter-example.
Under automatic memory management one of the most common uses of properties - to localise and handle retain/release - is removed. But if you need copy-on-assignment semantics properties are better than direct access.
Under manual memory management then properties have a distinct advantage - the memory management is localised, and with #synthesize provided by the language. However, as you remark, for reading a variable direct access is often fine.
Overall you know your class and which style of memory management you're using, so can pick the best solution for your private instance variables. There is no general "right" answer.

Problem with NSMutableString object declared as extern

in my app i need to pass a NSMutableString from one class to another so i put it extern.The problem is that when i run the app, the class does only access the string once, the second time the app crashes !! Obviously the NSMutablString becames nil after the first access. So i tried to figure out something: i converted the string into a C char. Well this time the app doesn't crash, but.. the value of the char changes everytime i call it !!
Am really confused: Please i need to know
Is there any way to maintain the value of the NSMutablString so it would be available everytime a class calls it ?
What causes the changing in the char's value ?
Thanks for any help
It sounds like you're doing some weird thing, really.
If you want to pass the NSMutableString instance from one object (source) to another (target), you should either assign it to the target object's property, or pass it via some method call.
The target object should retain this instance (either explicitly, or using 'retain' flag of the property), to ensure the instance is valid regardless of what the source object does. The target object should also release it, when it is no longer needed, otherwise you'd introduce a memory leak.
It is not really obvious, that "NSMutableString (pointer) becomes nil". Any invalid reference can lead to a crash when dereferenced, not only nil. Actually, my guess is that you're trying to access a deleted object.
I guess you've used [NSMutableString cStringUsingEncoding:] or similar method to get char pointer. Keep in mind that the pointer returned is valid for a limited time, check the docs.
Anyway, this is all pretty basic stuff. You should read Memory Management Progamming Guide and make sure you understand everything. It's simply essential to develop a stable Objective-C code.