My code is:
SCDownloadManagerView *downLoadMnger = [[SCDownloadManagerView alloc]init]
[self.vw_ownVw addSubview:downLoadMnger.view]
[self.vw_ownVw bringSubviewToFront:downLoadMnger.view]
I am getting this error on second line [self.vw_ownVw addSubview:downLoadMnger.view]
Please help me.
In my experience, what usually causes this error is when memory has been released prematurely. In this case, it is possible that your program is trying to use an array, but because it was not properly retained, the array was deallocated, and an NSString was allocated in the same spot. When your program tries to access the array, it sends the count message to where it thinks the array is, but because a string has been allocated there instead, the string gets the count message and this causes an error because strings don't respond to count.
The code you posted is not the cause of the problem, it is only the point at which this bug is manifesting. In order to find the cause, you need to review your memory management. Try running "Build & Analyze", the static analyser is very good at picking up obvious mistakes in memory management. Review parts of your code that deal with arrays, but keep in mind that the array in question could also be managed by another object outside of your code (such as a view or view controller) that you have released too early, etc.
Related
I have an iOS app that uses some legacy low level memory manipulation code using pointers. I'm debugging an issue where multiple threads are causing multiple copies of these code to be executed on global variables simultaneously and cause memory corruption by writing invalid length or overwriting data.
The effect is that the length of the buffer below may change. I've seen iOS throw EXC_BAD_ACCESS or EXC_BREAKPOINT as a result of these calls.
My question is - would iOS always throw exceptions when I use memcpy incorrectly, or will it complain only when I write outside my allowed memory?
In other words, is my code free to corrupt my memory and create invisible issues, without causing exceptions, as long as it does not step outside allocated memory or access deallocated memory?
NSData* buffer = ...
Byte *array = (Byte*)malloc(buffer.length);
memcpy(array, buffer.bytes, buffer.length);
The last time I checked or had such an issue it would only complain when outside your own allowed memory. In my situation I was writing over whatever objects followed the address I was trying to write to. The result was what seemed a random crash on objects as unrelated as even NSString.
My mistake was something like the following:
MyStructure *myStructure = malloc(sizeof(myStructure)); // Incorrect
MyStructure *myStructure = malloc(sizeof(MyStructure)); // Fixed
A simple autocomplete error which led to days long hunting of this bug. MyStructure was a fairly big one so accessing some property (both read and write) would in this case simply overflow and read/write through whatever was after it. It eventually randomly crash; sometimes bad access, other times just some random exception on a random object.
In my application, I have a series of long running processes. Sometimes, when the app gets backgrounded, one of these processes will return and try to notify other objects (which have been released) that it has completed, causing an EXC_BAD_ACCESS. Something like:
[process runForALongTimeWithCompletion:^(){
[possiblyReleasedObject heyTheProcessFinished];
}];
How can I check if possiblyReleasedObject has been released? Or, more precisely in my case, how do I check if it is dereference-able, such that referring to it won't cause a EXC_BAD_ACCESS error?
There is no way to (safely) check if a pointer to an object points to a valid memory location in Objective-C. You'll need to structure your program such that objects holding a pointer to possiblyReleasedObject retain it so that it doesn't get inadvertently released.
When an object holding a pointer to possiblyReleasedObject no longer needs it, it's generally good practice to set the pointer to nil after calling release in order to avoid accidentally dereferencing a bad pointer.
Im constantly being given an error that reads *** -[NSKeyValueObservance retain]: message sent to deallocated instance 0x86c75f10. I have tried running the Zombies template and here is the screenshot of what it provides.
It points to a managedObject, and I'm having trouble figuring out where the object is being deallocated. Here is the block of code that the compiler takes me to after each crash.
- (void)setIsFavourite:(BOOL)isFavourite shouldPostToAnalytics:(BOOL)shouldPostToAnalytics;
{
// check whether we need to generate preferences objects just in time
if(!self.preferences && !self.series.preferences /*&& isFavourite*/)
{
if(self.series)
{
[self.series addPreferencesObject];
}
else
{
[self addPreferencesObject];
}
}
//Crash In here
self.preferences.isFavourite = #(isFavourite);
self.series.preferences.isFavourite = #(isFavourite);
EDIT: If you need to see a larger size of the image here is a larger resolution link.
OK, I hit something similar and found a way to debug this kind of issue with NSKeyValueObservance. To debug, do the following:
In Xcode, open the "Breakpoint Navigator".
Add a new symbolic breakpoint with:
-[NSKeyValueObservance _initWithObserver:property:options:context:originalObservable:]
To that breakpoint, add an action and set it to "Debugger Command".
Set the following command: expr (void)NSLog(#"observer <0x%p>: %# <%p>, property: %#", $arg1, (id)NSStringFromClass((id)[(id)$arg3 class]), $arg3, (id)$arg4)
Click the "Automatically continue after evaluating expression".
Now you can run your application and take the steps necessary to reproduce your crash. And yes, you'll want NSZombies enabled. Note: it's going to run slow and you're going to get a ton of debug output, but just be patient. It'll get there eventually.
When you hit the crash when trying to message a deallocated NSKeyValueObservance, you'll be presented with the address of the original object. Highlight the address and hit cmd-e to enter the text in the search buffer. Then hit cmd-g find the next occurrence of the string in the debugger output. You're going to potentially find the address a couple of times, so look for the address that follows the observer <0x?????> output. The output on that line should tell you what object is being observed and for which property.
In my case, when I figured this all out, it turned out that I was observing a synthesized property that depended on an object in array and during a certain operation, the order of the objects in the array changed without doing the correct KVO notifications, and that caused my crash.
Are you using manual reference counting? If so, why? Convert your app to ARC. Manual reference counting is painful at best, and ARC is much better.
I am an experienced iOS and Mac OS developer and can do either, but I far prefer ARC. It's much less fussy and error-prone.
There is a feature built into Xcode that will convert your project to ARC for you. You might have to do some cleanup afterwords, but it's worth it.
If you do that your problem will likely go away.
As to the specifics, your screenshot is far too small to be able to read it. You will need to post a full-sized image if you want somebody to try to figure out what's going on.
However, in broad terms it sounds to me like you have an autorelease bug.
in manual reference counted code, lots of system method return objects that are "autoreleased." That means that when you receive them their retain count is positive (usually 1) so they stick around. However, they have been added to the "autorelease pool," which means that they are going to be released on the next pass through the event loop if nobody retains them first.
When you receive an autoreleased object you should either accept that it will be released once your current method returns, or retain it.
If you are trying to write Core Data code using manual reference counting and don't understand this then you are setting yourself up for failure.
Core Data is pretty complex, and you should have a solid understanding of Cocoa memory management before attempting to write a program that uses it, especially if you're using manual reference counting.
I have this error going on in Xcode:
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFString _isDecompressing]: unrecognized selector sent to instance 0x71863b0'
I have quite a bit of code and classes so I don't know what would need to be posted to start looking at this issue. If someone could give me some direction on how to start fixing this, it would be much appreciated. p.s. if there is anything else that needs to be posted tell me and I'll edit.
When you have unrecognized selector send to instance error, you have to check if you declared and implemented the method that is pointed out by the error, in your case _isDecompressing. If everything is ok on your class (the method is declared and implemented) then have a look at the class type that is calling the method, in your case NSString most of the time the class is wrong.
So in order to point out your problem, you are trying to call a method _isDecompressing on NSString which doesn't exist. So make sure every object that calls this method is of your desired type and not NSString
A good way to find the line that is causing the crash is to enable exceptions breackpoints.
The most likely cause of this crash is that you are sending a message to a deallocated instance of an object - try running your app with NSZomie's enabled - see e.g. How do I set up NSZombieEnabled in Xcode 4?
What is going on is that the memory used by your object gets marked as unused when deallocated and some other object gets allocated in that place. This object, however, is of a different class, hence the does not recognize selector message.
As noted in the comments, the way sending messages to deallocated instances manifests itself varies:
The object is allocated somewhere in memory - on a page, which is split into parts by an allocator - e.g. malloc. If the underlying allocator already returned the page where the object was to the kernel, then the app will crash with no log (EXC_BAD_ACCESS).
If the object was released and the retain count reached 0 it was deallocated, meaning just marking the memory on the page as free for future use. If you hence try to send another message to that object, the runtime will notice that the object has no retain count, hence was deallocated and will case the message sent to deallocated instance exception.
If, however, the memory that your initial object occupied was taken by another object in between, there's no way for the runtime to know that there was once an object you intend to call a method on, hence the unrecognized selector exception, since the class which the object belongs to is part of the object structure - the isa pointer. Nothing else is (or can be) checked by the run-time. For the runtime, it's a valid request to send a message to an object, however, there's no such method on the new object.
This can be potentially dangerous if the new object responds to the same message which does something lethal in one class, since the method is actually called on the object if it is a valid method name!
Of course, there are other scenarios, e.g. the object will overwritten by other data, hence the isa pointer points to a non-existant class and a crash will occur just as in the first place, since the OS will try to dereference an address that is not valid in the context of your process.
In the debugger console, use 'bt' to get a backtrace, then disassemble the first address in the backtrace the is noticeably smaller than the other values... the small valued addresses are your code.
This is easy to hit if you pull an image name out of, say, a JSON dictionary and pass it straight into something that expects a UIImage; since the values aren't type checked, the compiler will miss the error and you'll get a runtime crash.
(Ask me how I know!)
it's my call stack window when i got "Invalid Pointer Operation" Error :
CalStack http://m8spy.com//PersonalFs/M8SPY_Images/CallStack_1.png
What is the reason for this error?
Thank you
You've attempted to release memory that the memory manager doesn't recognize as belonging to it.
The exception comes from an object's destructor, which indicates that you're attempting to free an object that has already been freed. Otherwise, you're calling Free on an variable that never had a valid object reference in the first place; heed compiler warnings about uninitialized variables.
Please, see item "FastMM" in this article. Though it says about memory leaks, it is really an introduction to debugging memory managers, which are used to find problems with dynamic memory - just like your case.