Problem with NSMutableString object declared as extern - objective-c

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.

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!

Proper time to use the retain message?

thanks for viewing this post, it'd be great if you guys can help me out. I've been doing some objective-c and learned about the objective-c way of memory management, like making sure to call release whenever I own the object, when to call autorelease, etc. I also do not want to use ARC or the newly introduced GC because I like to manage my own memory, I plan to advance later on into iOS development, and I know it's a good practice to manage my own memory. But there's still one small detail that I seem to have hit a brick wall in. It has to do with sending objects the -retain message. I learned that sending the -retain message increments the reference count by 1. But would this be an appropriate time to send -retain? :
- (void) setName : (NSString* ) theName
{
// name is an instance variable of type NSString
[theName retain]; // Must release this
name = [theName copy]; // Must release this in dealloc
[theName release]; // decrement the reference count because of retain
}
Should I call retain here so that I own the argument temporarily and ensure it doesnt'
get released somehow before I get to use it?
Any help would be appreciated! Thanks!
No. You the object supplied as an argument to the method will generally be around until your method returns. You don't need the retain messages there. You copy the string here to keep it around after the method returns.
This is documented in Apple's Documentation on this page in the "Avoid Causing Deallocation of Objects You’re Using" Section. Specifically:
Cocoa’s ownership policy specifies that received objects should
typically remain valid throughout the scope of the calling method. It
should also be possible to return a received object from the current
scope without fear of it being released. It should not matter to your
application that the getter method of an object returns a cached
instance variable or a computed value. What matters is that the object
remains valid for the time you need it.
As an aside you really should consider using ARC. Its not good practise to manage your own memory. No matter how good one can be at managing their own memory the LLVM compiler is still better. Managing your own memory will lead to hard to troubleshoot issues caused only by yourself. It is an extra level of cognitive load that you really don't have to deal with and, when you finally let manual memory management go, you will breathe a sigh of relief at all the mental overhead you didn't even know was there.

What is NSTaggedDate?

I have an error that I can't understand, that is happening while I want to release all objects in an NSMutableDictionary.
It's happening for a custom object called body and the output is :
-[__NSTaggedDate body]: unrecognized selector sent to instance 0xffffffffffffffff
I found very poor informations about it on the Internet.
That's a private class of Apple. Errors like this usually occur when you mess up your memory management.
Why are you trying to release all objects in a dictionary? When you add an object to a dictionary (or an array), the dictionary will retain it (take ownership). And when you remove the object from the dictionary it will be released, you don't have to do that.
Did you already consider using ARC? It makes memory management a lot easier. You don't have to worry about retaining and releasing objects anymore.
It's an internal undocumented cocoa class. But you are not concerned with it as it's not really what's happening, it's a red herring that is probably happening for reasons that are complex to explain and irrelevant here.
Look at the reported address: 0xffffffffffffffff. That's a value that makes no sense. You should have got a segmentation fault, if it was not for that red herring.
You are for some reason sending the message body to an invalid pointer (maybe some corrupted data somewhere?).
Don't know this class, but it is probably a private class (my bet would be that it is a internal representation for NSDate objects that use the "tagged pointers" trick, but I'm just guessing).
Anyway your crash is happening not on an object called body, but when calling a method called body. And the crash is probably due to bad memory managment in your code that generates memory corruption
You should activate Zombies when running your app in debug to help you track over-released objects
You normally don't have to retain and release objects of an NSDictionary yourself, as container classes like NSArray and NSDictionary retain the objects they hold, and release them when the object is removed from them. So I don't see why you "want to release all objects in an NSMutableDictionary" : you only need to call removeAllObjects on that NSDictionary and you're done, no need to call release on the objects by yourself (neither do you need to call retain on the objects when adding them in the dictionary)
Whenever you try to set one data type to another data type like "if you directly assign an date component to text to an UIlabel" in this case I ll occurs
[toDateLabel setText:[tempArr lastObject]]; // Cause
[toDateLabel setText:[NSString stringWithFormat:#"%#",[tempArr lastObject]]]; // Solution

Unit tests for memory management in Cocoa/Objective-C

How would you write a unit test—using OCUnit, for instance—to ensure that objects are being released/retained properly in Cocoa/Objective-C?
A naïve way to do this would be to check the value of retainCount, but of course you should never use retainCount. Can you simply check whether an object's reference is assigned a value of nil to indicate that it has been released? Also, what guarantees do you have about the timing at which objects are actually deallocated?
I'm hoping for a concise solution of only a few lines of code, as I will probably use this extensively. There may actually be two answers: one that uses the autorelease pool, and another that does not.
To clarify, I'm not looking for a way to comprehensively test every object that I create. It's impossible to unit test any behavior comprehensively, let alone memory management. At the very least, though, it would be nice to check the behavior of released objects for regression testing (and ensure that the same memory-related bug doesn't happen twice).
About the Answers
I accepted BJ Homer's answer because I found it to be the easiest, most concise way of accomplishing what I had in mind, given the caveat that the weak pointers provided with Automatic Reference Counting aren't available in production versions of XCode (prior to 4.2?) as of July 23rd, 2011. I was also impressed to learn that
ARC can be enabled on a per-file basis; it does not require that your
entire project use it. You could compile your unit tests with ARC and
leave your main project on manual retain-release, and this test would
still work.
That being said, for a far more detailed exploration of the potential issues involved with unit testing memory management in Objective-C, I highly recommend Peter Hosey's in-depth response.
Can you simply check whether an object's reference is assigned a value of nil to indicate that it has been released?
No, because sending a release message to an object and assigning nil to a variable are two different and unrelated things.
The closest you can get is that assigning anything to a strong/retaining or copying property, which translates to an accessor message, causes the previous value of the property to be released (which is done by the setter). Even so, watching the value of the property—using KVO, say—does not mean you will know when the object is released; most especially, when the owning object is deallocated, you will not get a notification when it sends release directly to the owned object. You will also get a warning message in your console (because the owning object died while you were observing it), and you do not want noisy warning messages from a unit test. Plus, you would have to specifically observe every property of every object to pull this off—miss one, and you may be missing a bug.
A release message to an object has no effect on any variables that point to that object. Neither does deallocation.
This changes slightly under ARC: Weak-referencing variables will be automatically assigned nil when the referenced object goes away. That doesn't help you much, though, because strongly-referencing variables, by definition, will not: If there's a strong reference to the object, the object won't (well, shouldn't) go away, because the strong reference will (should) keep it alive. An object dying before it should is one of the problems you're looking for, not something you'll want to use as a tool.
You could theoretically create a weak reference to every object you create, but you would have to refer to every object specifically, creating a variable for it manually in your code. As you can imagine, a tremendous pain and certain to miss objects.
Also, what guarantees do you have about the timing at which objects are actually released?
An object is released by sending it a release message, so the object is released when it receives that message.
Perhaps you meant “deallocated”. Releasing merely brings it closer to that point; an object can be released many times and still have a long life ahead of it if each release merely balanced out a previous retain.
An object is deallocated when it is released for the last time. This happens immediately. The infamous retainCount doesn't even go down to 0, as many a clever person who tried to write while ([obj retainCount] > 0) [obj release]; has found out.
There may actually be two answers: one that uses the autorelease pool, and another that does not.
A solution that uses the autorelease pool only works for objects that are autoreleased; by definition, objects not autoreleased do not go into the pool. It is entirely valid, and occasionally desirable, to never autorelease certain objects (particularly those you create many thousands of). Moreover, you can't look into the pool to see what's in it and what's not, or attempt to poke each object to see if it's dead.
How would you write a unit test—using OCUnit, for instance—to ensure that objects are being released/retained properly in Cocoa/Objective-C?
The best you could do is to set NSZombieEnabled to YES in setUp and restore its previous value in tearDown. This will catch over-releases/under-retains, but not leaks of any kind.
Even if you could write a unit test that thoroughly tests memory management, it would still be imperfect because it can only test the testable code—model objects and maybe certain controllers. You could still have leaks and crashes in your application caused by view code, nib-borne references and certain options (“Release When Closed” comes to mind), and so on.
There's no out-of-application test you can write that will ensure that your application is memory-bug-free.
That said, a test like you're imagining, if it were self-contained and automatic, would be pretty cool, even if it couldn't test everything. So I hope that I'm wrong and there is a way.
If you can use the newly-introduced Automatic Reference Counting (not yet available in production versions of Xcode, but documented here), then you could use weak pointers to test whether anything was over-retained.
- (void)testMemory {
__weak id testingPointer = nil;
id someObject = // some object with a 'foo' property
#autoreleasepool {
// Point the weak pointer to the thing we expect to be dealloc'd
// when we're done.
id theFoo = [someObject theFoo];
testingPointer = theFoo;
[someObject setTheFoo:somethingElse];
// At this point, we still have a reference to 'theFoo',
// so 'testingPointer' is still valid. We need to nil it out.
STAssertNotNil(testingPointer, #"This will never happen, since we're still holding it.")
theFoo = nil;
}
// Now the last strong reference to 'theFoo' should be gone, so 'testingPointer' will revert to nil
STAssertNil(testingPointer, #"Something didn't release %# when it should have", testingPointer);
}
Note that this works under ARC because of this change to the language semantics:
A retainable object pointer is either a null pointer or a pointer to a valid object.
Thus, the act of setting a pointer to nil is guaranteed to release the object it points to, and there's no way (under ARC) to release an object without removing a pointer to it.
One thing to note is that ARC can be enabled on a per-file basis; it does not require that your entire project use it. You could compile your unit tests with ARC and leave your main project on manual retain-release, and this test would still work.
The above does not detect over-releasing, but that's fairly easy to catch with NSZombieEnabled anyway.
If ARC is simply not an option, you may be able to do something similar with Mike Ash's MAZeroingWeakRef. I haven't used it much, but it seems to provide similar functionality to __weak pointers in a backwards-compatible way.
this is possibly not what you're looking for, but as a thought experiment I wondered if this might do something close to what you want: what if you created a mechanism to track the retain/release behavior for particular objects you wanted to test. Work it something like this:
create an override of NSObject dealloc
create a CFMutableSetRef and set up a custom retain/release functions to do nothing
make a unit test routine like registerForRRTracking: (id) object
make a unit test routine like clearRRTrackingReportingLeaks: (BOOL) report that will report any object in the set at that point in time.
call [tracker clearRRTrackignReportingLeaks: NO]; at the start of your unit test
call the register method in your unit test for every object you want to track and it'll be removed automatically on dealloc.
At the end of your test call the [tracker clearRRTrackingReportingLeaks: YES]; and it'll list all the objects that were not disposed of properly.
you could override NSObject alloc as well and just track everything but I imagine your set would get overly large (!!!).
Even better would be to put the CFMutableSetRef in a separate process and thus not have it impact your program runtime memory footprint overly much. Adds the complexity and runtime hit of inter-process communication though. Could use a private heap ( or zone - do those still exist?) to isolate it to a lesser degree.

Why does a passed-by-value struct parameter get corrupted?

This isn’t the original code (I stripped things back in trying to simplify for debugging), but it does display the problem. On the face of it, looks simple enough:
- (void) testMethod: (TouchData) toi {
TouchData newToi = toi;
NSString *test = #"test string";
NSLog(#"string: %#", test);
// in ‘real’ code I pass the struct back
// It’s void here for the simplest possible
// case
}
TouchData is a struct, declared thus:
typedef struct {
Entity *owner;
CGPoint startPos;
CGPoint latestPos;
CGPoint startOfStraightSwipePos;
NSTimeInterval startTime;
NSTimeInterval latestTime;
NSTimeInterval startOfStraightSwipeTime;
CGFloat latestSpeed;
NSMutableArray *gestures;
BOOL isOfInterest;
} TouchData;
When I step through testMethod in the debugger (watching toi) on hitting NSLog (which doesn't even involve toi), all toi member values suddenly zero out. This doesn’t happen to the copy (newToi). It doesn’t happen if I pass the struct in by reference. It doesn’t happen if replace the testMethod invocation directly with the method body (ie. if I run these lines in situ rather than calling into a method). It doesn’t happen if I change the toi parameter type to a dummy struct with a couple of int members, created just before the call.
It might worth pointing out that testMethod is only called from within its own
class, and that the caller has just extracted the struct from an NSMutableDictionary (via unboxing an NSValue). But given that (a) the struct is
passed into the method here by value, and (b) that on entry its members as shown
by the debugger are all as expected, I don’t see that this can be causing a problem. There is also the thorny issue of the two object pointers in the struct, but in other contexts they’re working out OK, and they check out in the debugger on entry to the method, so I don’t think I’ve missed essential retains.
I presume I’m running into some kind of heap or stack corruption, but I’ve no idea how or why. I’m new to Objective-C, and have previously worked in
garbage collected environments, so my memory management experience is limited. It’s entirely possible that I’ve missed something painfully obvious.
I expect someone will tell me to make TouchData an object type instead, and indeed I may well go that way. I also have a couple of tested workarounds, ie. to either work on a copy, or pass the struct in by ref. But I’d really like to know what’s going on here.
If toi is not used after the line TouchData newToi=toi, the compiler can do whatever it wants to do in the stack memory where toi originally was placed after that line. For example, it might reuse the stack memory when calling another function, in this case NSLog.
So, watching toi by a debugger might show something strange. The compiler does often do these things, in particular if the optimization is turned on. Even with no optimization there's no guarantee that the stack location of toi is left intact after it's last used.
By the way, you said having object pointers inside toi didn't cause problems, but it's a tricky situation and I recommend strongly against that practice. Follow the standard retain/release rules; otherwise, another programmer who takes a look at your code (who might be yourself two years from now) would be totally confused. Also, the static analyzer (which can be accessed by doing Build & Analyze in XCode) might be confused and might give false positives. So, don't do that.