function parameters not retained using Arc? - ios

EDIT: This is for a static NSMutableDictionary, not a class member. I see a lot of answers thinking it's a class member, sorry about that. Thanks for the quick responses.
I had a working piece of code, but it was used 2x, so I wrote a convenience function:
- (void) initializeDictionary:(NSMutableDictionary*)mutableDict fromPathName:(NSString*)path
{
mutableDict = // get from file, init if not there.
}
Then I noticed nothing was saving. Stepping through the code, the function creates a dictionary, but the "passed in" value is still nil upon returning. This completely blows away my understanding of pointers (don't take this the wrong way, I'm very comfortable). But their purpose, I thought, was to let you "pass the address" so I could hydrate the thing it points to.
since mutableDict is the "value copy", ARC appears to be wiping it out. I'm asking here because
the other questions have the opposite question "Why is this being retained?" and
It doesn't seem right. Your very first tutorial in any pointer language is "so you can mess with the original value". Does Arc really do this? Is there a concept I'm not getting?
And of course, I may be overlooking something simple.
I seem to have solved it by doing the writeback trick I found elsewhere:
- (void) initializeDictionary:(NSMutableDictionary* __strong *)mutableDictionary fromPath:(NSString*)path;
and using the & to call and * deref to change the value. It just seems far less than elegant.

You pass a pointer of NSDictionary. If you change the pointer value of mutableDict (by allocation or assignment) this will NOT be reflected on the variable passed as this function's argument and since mutableDict is locally defined in the function it will be released by ARC automatically. (Do not forget that even for pointers the address is copied when passed to a function).
The reason that your second solution works is because you pass a pointer to a pointer (not sure if strong is needed there). The value of *mutableDict will be reflected outside since you update a value in the address pointed to by mutableDict. This value is the address of your allocated dictionary and since you change it via a pointer it will be reflected outside the function.

To do what you want you use multiple indirection
- (void) initializeDictionary:(NSMutableDictionary**)mutableDict fromPathName:(NSString*)path
{
mutableDict = // get from file, init if not there.
}
Notice the parameter is (NSMutableDictionary **), a pointer to a pointer to an NSMutableDictionary.
To call the method you need to create a pointer and pass it in like this:
NSMutableDictionary *mutableDictionary;
[self initializeDictionary: &mutableDictionary fromPathName:...];
And on return, the mutableDictionary variable will have been initialised by the method.
However, It's probably easier to just return the dictionary from the method rather than doing it this way.

In Objective-C if you define a variable in a method, the variable is visible only in that method.
If you need to save the variable to use it outside, you need to "return" it from your function. What you did wasn't a trick, is another way of returning a variable.
Try with:
- (void)initializeDictionaryFromPath:(NSString*)path {
NSMutableDictionary *mutableDict = // your initialization
return mutableDict;
}
Then you can define your dictionary with this code:
NSMutableDictionary *mutableDict = [self initializeDictionaryFromPath:path];

Related

XCode 6.3 Warning : Comparison of address of 'myObject' not equal to null pointer is always true

After updating to XCode 6.3, compiler started giving this warning.
Comparison of address of 'myObject' not equal to null pointer is always true.
Here is my piece of code,
Scratching my head with it, but didn't find any solution or workaround to get rid of this warning.
My question is linked with question over here. But, it can't be solved using answer discussed.
Any help will be welcomed :)
Correct way of checking the pointer is
if (anotherInView != nil) {
}
You are comparing address of a variable with the NULL. Every variable has an address you can't have a variable whose address is NULL, you can have a variable whose value is NULL
Also anotherRect != NULL is again not valid. anotherRect will always have a value as it's a struct
There are four mistakes here. The first two are that you aren't setting any initial values for the CGRect and UIView variables, so there's no way to detect a failure. Try setting the CGRect to a zero-width, zero-height rect initially if you think that is useful, and set the UIView to nil.
The third and fourth mistakes are that the address of a local variable is never NULL. (Note that this is not true for global variables in libraries, as I mentioned in another comment—the address of an NSString pointer constant might be NULL if the symbol didn't exist on the version of the OS you're running—but for local variables, you're guaranteed an address up to the point where your stack overflows and your app crashes.)
I'm also puzzled by why you're calling a delegate method yourself. Normally, the OS itself calls those methods, so calling them yourself is somewhat atypical usage. To be fair, I've done it on occasion when a delegate method performs a computation that I need somewhere else in the code, and I've also done it when implementing delegates that call other delegates, but in the context of this question, it seemed like a potential mistake.
For the first instruction, a changed to :
if (!CGRectIsNull(anotherRect)) {
}

How to get the address of an object in an NSMutableArray

How can I get the Address of an object stored in a NSMutableArray?
I have something like this:
class member variable in .h:
MyClass *__strong*_selectedobject;
in a function in .m:
MyClass *objReference = [_messageBoards objectAtIndex:idxInCaseOfContract];
_selectedobject = &objReference;
the problem is, that _selectedobjectis nil as soon as the function finishes.
_selectedobject is an instance variable within a singleton class. It works with other objects which are not within an array. Also, the object within the array is not suddenly nil, it is just the reference.
You can not get pointer to a position inside an array in Objective-C.
If you need to retain position in an array, so that if another object is written there you'll have it instead of the old one, then save index of that position (and retain the array too if needed). Mind that modifications to the array may render the index invalid.
If you need to retain only the object which was read from array at that moment, simply retain that object. Object address is the object pointer itself, there are no extra indirections.
UPDATE
I'm just posting here how you can store reference to address in object(as question was originally about that), however I strongly advice anyone to think again if this is actually needed:
#interface MyClass : NSObject
{
NSMutableArray* test;
__strong id* foo;
}
*foo = [test objectAtIndex:2];
ORIGINAL ANSWER
As #Vijay-Apple-Dev.blogspot pointed out you are missing something very important about memory - you are making _selectedobject to point to address of temporary variable(objReference) instead of object in memory([_messageBoards objectAtIndex:idxInCaseOfContract]). All method variables becomes nil after their method goes out of scope, and thats why your reference becomes nil(although array is still alive and object is there). Simply do not use local variable and everything should be fine.
Side note - what's the purpose of using address reference instead of object pointer? If you think you're gone save memory you are wrong, as ARC(and MRC also) are working differently ;)
MyClass *objReference is local variable to the method. So once it method finishes, everything will be gone from memory. If you want to keep them, then you have retain them in header file(.h) as instance variable.
#property(nonatomic,retain) MyClass *objReference;
then
self.objReference = [_messageBoards objectAtIndex:idxInCaseOfContract];
NOTE: You must use the self dot syntax when u retain the object. otherwise wont work.

setString on nil object with categories

It looks to me like sending setString: to a NSMutableString that hasn't had init called on it yet does not call init on it's own. For example:
NSMutableString *string; // Declare, but do not init yet
[string setString:#"foo"];
NSLog (#"%#",string); // Prints "(null)"
I'd like to overwrite this behavior, so that essentially
- (void) setString:(NSString *)aString
{
if (!self)
{
self = [self initWithString:aString];
}
else
{
[super setString:aString];
}
}
I could do so with a subclass, but I would have to go through my project and replace all my NSMutableStrings with my subclass, which is a pain. I was looking at the Apple Docs and it looks like what I want to do is create a Category for NSMutableString. I haven't used categories before, so I got a couple questions:
First, it looks like categories only allow me to add new methods, it doesn't allow me to overwrite existing methods. I suppose it is easy enough to just create a setStringWithInit: method that does what I want, so this first issue isn't really an issue after all (although I still have to do a find-replace through my project for setString, but oh well).
Second, and more importantly, how do I check if the sender of my new method is nil? If setString: returned something other than void, I think I could get it to work, but that's not the case here. How do I get the if (!self) check from my code above to work with a category?
Or are categories not the way to go for this kind of thing, and I'd just be better off sub-classing after all?
EDIT:
So the strings I'm using this on will actually be #propertys of a custom NSObject subclass. In my code, I'll actually be calling [myObject.someProperty setString:#"foo"];, and the debugger is showing me that someProperty is nil when I try to do this. Also, in other parts of my app I'm checking if (!myObject.someProperty) to see if that property has been used yet, so I don't want to just automatically self.someProperty = [[NSMutableString alloc] init]; in the init method of myObject's class.
Although now that I think about it, I think I can get away with replacing if (!myObject.someProperty) with if ([myObject.someProperty length] == 0), which would allow me to go through and alloc-init things right away. But if I'm initializing everything right away, that will create some memory space for it, correct? It's probably negligible though. Hm, perhaps this is what I should be doing instead.
The proper code would simply be:
NSMutableString *string = [NSMutableString string];
[string setString:#"foo"];
NSLog (#"%#",string);
Why would you not initialize the variable? There is no need to override setString: or any other method. Don't try to treat NSMutableString any differently than any other class.
Besides, overriding setString: still won't solve anything. As long as the pointer is nil you can't call a method on it.
You are marching down a path to madness. Abandon hope, all ye who enter here!
Do not try to change the language semantics so that sending a message to a nil object somehow magically creates an instance of the object. That is not how the language works.
What you are trying to do is likely impossible, and if you were able to succeed, you would create programs that are fundamentally incompatible with standard Objective-C. You might as well found a new language, Objective-D
It is legal to send a message to a nil object in Objective C. The result is that the message gets silently dropped, and nothing happens. In many other object-oriented other languages, sending a message to a nil object/zero pointer causes a crash.
The semantics of of Objective C object creation are:
First allocate memory for the object using the class method alloc:
NSMutableString* aString = [NSMutableString alloc];
Then send the newly created object an init method to set it to its initial state:
aString = [aString init];
These 2 steps are just about always combined into a single line:
NSMutableString* aString = [[NSMutableString alloc] init];
Classes sometimes include shortcut "convenience" methods that do the 2 step alloc/init for you, and return an object in one call, e.g.:
NSMutableString *aString = [NSMutableString stringWithCapacity: 50];
Do not try to fight this convention. Learn to follow it. If you cannot tolerate this convention, program in a different language. Really.
You can reimplement a method without subclassing by using method swizzling. Here's a tutorial. There are 2 reasons not to do it here though.
it would be against the good Objective-C practices, since your
setter will also be an init method. Not good.
As #rmaddy correctly points out, calling setString: on a nil object will do
nothing. Even if you do override the method.
So I recommend creating a category on NSMutableString, and implementing [NSMutableString initWithString:] there. It is a much cleaner solution.
You cannot really do that - you have a method which can be called only on instance of this object, so you will have to create it first anyways to use it.
In your code it will be "nil" anyways - it won't create itself.
Why are you doing it instead of just:
NSMutableString *string = #foo";
I cannot imagine a reason to avoid allocating an object
macros FTW!
#define setString(X,Y) if(!X){X=[[NSMutableString alloc] initWithString:Y];}else{[X setString:Y];}
When I try to assign a value with this:
It will always be initialized first
It won't be initialized until I try to give it a value
It doesn't clutter up my code
It still gives a warning if X isn't an NSMutableString, or if Y isn't an NSString or NSMutableString
I haven't tested for if Y is nil, but I expect it will cause a crash, which is what I want.
Drawbacks:
I still have to remember to always use my setString() instead of the stock setString:
I'll have to do something similar for any other setters I call (the only one that I'm worried about off hand is setValue:forKey:, which I use extensively - one step at a time I guess) - a one size fits all solution would have been nice - maybe a topic for another question.
Whatever I pass in has to be a NSString before I pass it, I cannot convert it to a string in line - but at least I get a build error if I try to do so, so it isn't up to me to remember to do so (still adds clutter though)
NSMutableString *X;
int y = 0;
setString(X, [NSString stringWithFormat:#"%d",y]) // <--- Doesn't work
NSString *Y = [NSStirng stringWithFormat:#"%d",y];
setString(X,Y) // <--- Does work

Accessing obj as property vs method param (style preferences)

When it comes to accessing objects from different methods in the same class, from what I understand, these are two ways to do it. Given that I DO want to hold a property pointer to this object, which is the better way to go about this? I've been thinking about this for a while, and wondered if there is a preference consensus.
#1:
NSArray *array = ... // Get array from somewhere
self.myArray = array;
[self doSomethingToMyArray];
This method takes no parameter and accesses the array via its own property via self
- (void)doSomethingToMyArray
{
// Do stuff with/to the array via self.myArray
[self.myArray ...];
}
Vs #2:
NSArray *array = ... // Get array from somewhere
self.myArray = array;
[self doSomething:array];
This method takes an array and accesses the array via its own method parameter
- (void)doSomething:(NSArray *)array
{
// Do stuff with/to the array via method parameter "array"
[array ...];
}
I think it's primarily going to depend on what doSomethingToMyArray does and who calls it.
Fairly obvious comments:
if you want to do that to more than one array, you need to take an argument;
if what you're doing is actually logically more to do with the array than with your class (e.g. you've implemented randomisation of the order of the array) then it'd be better as a category on NSArray rather than being anywhere in that class at all;
if there's any possibility of subclasses wanting to redefine the manner in which the array is obtained then you'll want to invoke the getter somewhere;
similar concerns apply if a subclass or an external actor should be able to intercede anywhere else in the process.
Beyond those concerns there are a bunch of us that just prefer this stuff to be functional anyway — noting that you're doing something to the array, not with the array, in which case you'd tend more towards self.myArray = [self processedFormOf:array] (or self.myArray = [array arrayByDoingSomething]; if the category tip makes sense).
So, ummm, I don't think there's a clear-cut answer.
That depends on what you want to do, just by reading it:
doSomething:array
I would assume the above method takes ANY array and performs an action, whereas:
doSomethingToMyArray
with this method you are describing the intention of doing something to your instance's array. Inside this method (given that you followed Apple good coding practices and you synthesized your property to _myArray) , you could either go with:
[self.myArray message]
or preferably
[_myArray message]
Your second option is sort of silly. If you're storing a pointer in an instance, then it's so that you can use it later (within that instance) without needing to pass it around whenever you call a method.
This is also dependent on whether you're using ARC or not (use ARC if this is a new project). In a non-ARC project, self.myArray = foo; will do a very different thing than myArray = foo; (the self. syntax calls a property, which in many cases will correctly retain the thing you've assigned). In an ARC project, they'll generally have the same behavior, and there's less room for error.
Personally, in my ARC projects, I do not use the self. syntax from within a class, since it's just extra typing for the same effect. This ties in nicely with the new usage of #property, where you're no longer required to write a #synthesize block, and Objective-C will automatically generate an ivar for you, with the name of your property prefixed by an underscore, i.e. _myPropertyName. That makes it very clear visually when you're accessing code from outside the class (crossing the encapsulation boundary), where things will look like foo.bar = baz; versus inside the class, where it's just _bar = baz;.
IMHO, clearly, a function call would incur an extra overhead.
you would have to allocate an object pointer (though minimal) over the stack (extra memory)
Have to pass it (extra processing)
Property is actually a small function call unless you have made customizations to the getter. I also assume that compiler may have its own optimizations put in place for such accessors so that you can access them with minimal overhead, though I do not have any source to cite this.

Releasing Singletons

I was wondering how you would release a singleton
+ (DSActivityView *)activityViewForView:(UIView *)addToView withLabel:(NSString *)labelText width:(NSUInteger)labelWidth;
{
// Not autoreleased, as it is basically a singleton:
return [[self alloc] initForView:addToView withLabel:labelText width:labelWidth];
}
When analysing this using the analyse tool i get the following error :
Potential leak of object on line 90. which is the line that returns.
I have tried autorelease that solves the error message problem but im not convinced its the right solution since i read that autoreleasing singletons is not good. Would someone be able to assist me in identifying how best to release this object?
Thanks
The reason why the analyzer gives you the warning is, basically, the method name:
+ (DSActivityView *)activityViewForView:(UIView *)addToView withLabel:(NSString *)labelText width:(NSUInteger)labelWidth;
according to Objective-C conventions, all method names starting with "create"/"new"/... return a retained object; your method falls under the category of convenience constructors, which are expected to return autoreleased objects, hence the warning.
On the other hand, you say this is a singleton, but in fact it is not. So, you could possibly end up calling this method more than once and thus have an actual leak. A basic way to make your method safer (and more singleton-like) is:
+ (DSActivityView *)activityViewForView:(UIView *)addToView withLabel:(NSString *)labelText width:(NSUInteger)labelWidth;
{
static DSActivityView* gDSActivityViewSingleton = nil;
if (!gDSActivityViewSingleton)
gDSActivityViewSingleton = [[self alloc] initForView:addToView withLabel:labelText width:labelWidth];
return gDSActivityViewSingleton;
}
This would both make the analyzer relax and give you more safety in front of the possibility of misuse of the method.
Use autorelease. There's no reason not to. Basically ownership of the object belongs to the object, so you're never going to be able to manually release it. As its a singleton it doesn't matter if you don't own it because presumably next time you call it and need it in scope you'll use another convenience method and it will get instantiated again.
If you want to have ownership of the object then you will need to instantiate it as normal and then you will be able to retain and release it.
Also, read sergio's edit about it not being a "proper" singleton. :p
Also, if you can, convert to ARC and you won't have to worry about this!
U are doing it wrong. Consider:
If you calling activityViewForView multiple times, you won't get get the same object over and over again. It only would initialize a new object and give you the pointer to it!!!
To make this thing a singleton, you have to store the created object in a constant variable and make sure, you have a reference to this object all the time your app is running (for instance declare your pointer to this object in appDelegate).
Then every time you call activityViewForView you have to check the constant variable if it is pointing to a valid object. If so, return the valid object, if not, create it and store it in your constant static variable (creation is done only once).
If you do use ARC you're all set. If not, release your object (use dealloc method)

Resources