Why isn't my WTArchitectView being released under Obj-C + ARC? - ios

The second time I try to present a view controller with a WRArchitectView it fails with a large error stating that a second architect view is attempting to be allocated before the first has been deallocated. I've checked up an down, have ARC enabled, the view controller is completely deallocated. I even have a branch which is working with an identical view controller, so what could be retaining the WTArchitectView?

I was writing JSON in a Swift Utility class while the view controller was instantiated which wasn't being handled well. I was getting an error along the lines of *** WebKit discarded an uncaught exception. Somehow, parsing malformed JSON with NSJSONSerialization and not handling the exception halts some Wikitude internals, which means something internal was retaining the view. Fixing my JSON allowed Wikitude to dealloc properly.

Related

strange error when reload tableView

I have a very general table view.
when it is refreshed, it will go to fetch list of objects from Parse. Analyze these data in a dispatch_async queue, then refresh table view. Most time, it has no problem, but some time reloadData() crash
Is it crashes because the tableView is reloading data when I call it? (when the tableview is init, reloadData may be called automatically) How to avoid this error? ( there is no error message in console )
EDIT:
I tries to put ?, but does not work
This happens when your tableView (or whatever object you're sending the message to) is nil. So sometime before your async call dispatched this on the main queue, your tableView got dealloacted.
Check this link out for some info:
http://www.touch-code-magazine.com/how-to-debug-exc_bad_access/
You will get EXC_BAD_ACCESS error mostly in the following scenarios:
You are trying to access an object that is not initialized.
You are trying to access an object that no longer exists. Either it’s being released or it’s nil. In ARC mode, make sure you take ownership of the object that you want to use.
You are passing an message to an object that the object doesn’t understand.
It can also happen for bad typecast. Like the lines below where I am trying to access an int with %# in stead of %d.
int myAwesomeInt = 9;
NSLog(#"%#", myAwesomeInt);
How to debug:
Identify what you did that caused the crash. Did it crash while view of a particular view controller didLoad or in a delegate method or on a particular action. That will often help to find the object that is casuing the error.
(In your case look at what specifically happens when you are reloading the table. Do a stack trace line by line and see what your code is doing during a reload)
Most of the time “NSZombies” can help to identify the dead object. You can enable NSZombies by editing your scheme Product -> Edit Scheme -> Diagnostics.
If you still don’t find the root cause then always go backwards from child view controller to parent view controller to see what object needs to be retained or what message needs to be passed properly.
Look into Static Analyzer and Instruments for advanced debugging.
Credit:
The Basic Troubleshooting guide
Hope this helps. Good Luck

[__NSCFString count]: unrecognized selector sent to instance 0x75bc230'

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.

'NSInvalidArgumentException', reason: '-[__NSCFString _isDecompressing]: unrecognized selector

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!)

Debugging strategies for over-retain in ARC?

I've got some objects that are passed to a lot of different views and controllers in my application. They're not getting deallocated when I expect them to. Obviously there is an errant strong pointer somewhere, but the surface area of where it could be is very large--these objects are moved into and out of a lot of different data structures.
My usual go-to solution here is Leaks (which reports no cycles) and Allocations (which lists 500+ retain/releases for this object). Is there any way to reduce my search space here?
Ideally there would be a tool that would let me type in a pointer and see all the strong references to the object, and I could probably eyeball the list and find the extra reference in about 60 seconds. In fact, there is such a tool -- the Object Graph instrument -- but it's not available for iOS software.
You want the Allocations instrument. To track an individual object type, start the application. You need to create a heapshot at every significant event (I usually create them at points when you've just transitioned to or from a view controller).
Once you've got a heapshot that should have the object you're interested in tracking down, then you should be able to find that object type under the heapshot's disclosure triangle. For each object of that type, you can get a history of what retains and releases have been sent to that object by clicking on the arrow in that object's row.
The simplest method to identify whether there is retain cycle or not by just putting a breakpoint in your controller's dealloc()/deinit()(swift) method and whenever you pop your controller check this methods getting called or not if there is retain cycle present in your controller this methods won't get called.
Swift
deinit {
print("Memory to be released soon")
}
Objective C
- (void)dealloc {
NSlog("Memory to be released soon");
}
If you want to get more details about the strong references and root causes you should go with Instrument as the other answer.

iOS Xcode 4.3 Table View Controller & XML Parsing

I used a tutorial that I found previously mentioned on stackoverflow, however I am running into an issue when I try to incorporate the code into a Storyboard I've created.
My storyboard is setup as follows:
Navigation Controller -> Table View Controller (static content) -> Table View Controller (where the XML should appear)
I get the following compiler error when I use the simulator and go to the Table View Controller where the XML should get output to:
unrecognized selector sent to instance 0x6b5f300
From what I gather, the problem is with the Table View Controller that I have setup. I specify its class to point to the custom viewcontroller implementation files I've created, where all of the code is from the tutorial.
I've gone through every one of the tutorial files line by line to make sure I've used them properly in my own project and they all match. I have to believe the issue is a difference between the old-style of .xib files the tutorial uses and the new style of using the storyboard to layout the app. I even made sure the tutorial code compiles and works properly in my struggle to figure out what I'm doing wrong here.
Should I be creating a different type of view controller for the XML code to be displayed on versus using the drag-n-drop table view controller object the storyboard provides?
unrecognized selector sent to instance 0x6b5f300
This means that you're sending a message to an object that doesn't understand that message. You may have forgotten to implement some method that you're calling, or you may have an object of a different type than what you expect. Occasionally, it can also mean that you've got a bad pointer, i.e. there just happens to be a new object located at the same address that was previously used for some other object.
Take a look at the object at 0x6b5f300. What type of object is it? What message are you sending to it? Answering these questions should get you a lot closer to an answer.

Resources