Why when I tests my controllers in Xcode everything is fine, but deinit methods are not called. Is it correct?
While app works normally, it is fine, but not for UITest target.
For complicated structures simulator allocate over and over more objects, and... do not deallocate it at all. So, quite often on slower machines the app sometimes quits without any reason... and tests cannot be fulfilled.
Using Xcode 8, iOS 10, macOS Sierra.
I can not answer your question definitively without seeing a sample of the test code, however, your case makes me suspicious of a couple things.
Basically what is happening is that the app is creating new processes for each test you run. A memory leak somewhere inside the code would be the first problem to investigate. If you are leaking memory, the testing framework spinning up a bunch of processes could cause the crash and allow that issue to fly under the radar during normal running.
Also, unless you are de-initializing the controllers explicitly through the tear down function in your test class, the process is generally just killed at the end of the test. If you want to test your reinitialization I would suggest explicitly triggering a tear down in the tests to test your memory allocation behavior. Also, the Xcode Analyze feature may be of use to you here.
If you could post a sample of your test code that would be a great help and I will edit my answer accordingly.
Make sure deinit is not empty.if its empty then it will never work.put whatever you need to deallocate and check whether its working or not.
My suggestion
better to use dealloc method rather than using deinit.
Related
I remember from watching CS193P from Stanford University on YouTube (yes, I'm a smart bunz)... that there's this thing called a memory leak or "retain cycle" -- something really bad -- that can happen when you do things like this:
referencing self. within a completion block
referencing self. within a timer callback
referencing self. within a SyncQueue.sync() method
referencing self. within a DispatchQueue.main.async() method
The solution generally seems to be to use the "weak self" reference instead.
I have 104 of these asynchronous self. references in my ViewController which is why I am a little worried.
HOWEVER... this app is a single-page app... and ALL these self. references are pointing to this main ViewController (or one of its permanent sub-views) which is always there, never dismissed, and never "popped from the stack."
My app seems to work fine... and I don't see the total memory usage going haywire or anything... So does that mean I can leave my (ViewController) code as-is in this regard?
Thanks for help!
Here are two situations where you may regret not fixing your code:
If the device runs low on memory when your app is in the background, there are aspects of your view controller and its views that can be deleted. See this (admittedly old, but still interesting) article. This could easily affect your app more significantly in a future iOS version, or maybe even now depending on what your code is doing.
Jump 6 months ahead, where you or someone else on your team is borrowing some of your code for another app. You (or they) will likely get burned. Best to just fix the code now. The fixes shouldn't cause a major refactor, but if you find one that does, you could always insert a big warning comment at that line instead.
Please, anyone, help me: Is calling NSUserDefaults's synchronize() method mandatory?. If I don't call it, what will happen? My application is working fine without it.
No.
Since iOS12, it isn't mandatory anymore.
Apple says:
This method is unnecessary and shouldn't be used.
You can find more information on iOS12 release note:
UserDefaults
NSUserDefaults has several bug fixes and improvements:
Removed synchronization requirements. It's no longer necessary to use synchronize, CFPreferencesAppSynchronize, or CFPreferencesSynchronize. These methods will be deprecated in a future version of the OS.
Now that you don't need to call these synchronization methods, the performance characteristics of NSUserDefaults and Preferences Utilities are slightly different: The time taken for enqueueing write operations is now paid by the writing thread, rather than by the next thread to call synchronize or do a read operation.
From the docs:
Because this method is automatically invoked at periodic intervals, use this method only if you cannot wait for the automatic synchronization (for example, if your application is about to exit) or if you want to update the user defaults to what is on disk even though you have not made any changes.
Meaning that if you kill the app right after something is written to the defaults without the periodic interval catching it, it will get lost. You probably did not kill the app right after a write event yet which is why your app seems to work fine so far.
Normally it works perfectly fine and you only have to use it in special cases, for example when the app will close directly after writing to NSUserDefaults. So you can simply add the synchronize method to the corresponding AppDelegate-method.
As others have said, you don't normally have to call synchronize at all.
Normally the system calls it for you so your defaults changes get written.
However, when working with Xcode it's pretty common to terminate your app by pressing command period or clicking the stop button. In that case it terminates the app without warning and your user defaults changes will quite likely not be written out, and will be lost.
This can be a good thing or a bad thing, depending on what you want. It's certainly confusing.
You can "fix" it by calling synchronize each time you make a change, or on some time interval. However that does slow your app down and increase it's power requirements (both by very small amounts.) If you are in a loop, writing changes to 10,000 server or Core Data records, and you change user defaults after each pass, then calling synchronize after each one might have a measurable effect on app speed and on battery life. In most cases you're not likely to notice the difference however.
My app gets stuck for a specific operation and that operation is too big having so many method calls and services requests, so i cannot put breakpoints on each method and debug, is there any other way i can get to know where exactly my app is stucked in xcode?
The operation wasn't too big to write the code, so it isn't too big to add breakpoints, logging statements, assertions and so on.
The only other way that works sometimes is taking a long shower in the morning, not thinking about work at all, and suddenly the realisation what you did wrong jumps to your mind. It has worked for me sometimes, but the first method is more reliable.
If you have reason to believe that the most time is spent in one operation, just let it run with the debugger attached and then press the pause button and see where you are...
A somewhat niftier approach would be to start with Instruments (i.e. the Time Profiler). It's easy to use and should be the first weapon of your choice for performance issues.
You can set a conditional break point in Xcode to debug a specific condition, for more detail go through Jeffrey Sambells blog!
My project doesn't use ARC and support iOS 4.3+, used Parse,Crashlytics framework.
I tested by Instruments about leak memory.
This is result. The problem is that all thing is in library system. Nothing is related to my code.
How can I fix them? Somebody help me!
Click to see fullsize http://i.stack.imgur.com/ZRrkQ.png
You application started a system thread shown in Instruments. It is not clear how. The thread doesn't call your code directly. It is somehow related to private DataDetectorsUI.framework; that calls CFStringTokenizer... You do not create this thread directly, you ask iOS to do something. Can you guess what is that and what part of your code triggered spawning the thread?
What are trying to do? Is it possible that you do not close the task properly?
DDOperation is a NSOperation subclass that is part of the Data Detection framework in iOS and OS X. I can't pinpoint your leak to a specific line either, but it appears like you are leaking something that is created indirectly when you use NSDataDetector. Check if you are retaining anything when using the block based enumerator but never releasing it.
I have a setup where all of my singletons' live in an extern NSDictionary (I need it globally visible, since I make many subclasses from a base singleton object with some common features).
Everything is fine, but on an iPad 1 running iOS 5.0, when user puts the application to background (not terminates, just press the home button), this dictionary gets released (so all of my singleton services, subclasses, etc.). The more interesting, they get recreated when I switch back to the application, but "sometimes" they're not, and my application behaviour gets unpredictable.
I've put __strong before the declaration, but it results in the same. It is quiet harmful when my singletons are destroyed/created all over the time, since they are storing runtime user/application states.
It is important that I'm debuggin with Fastest, Smallest Optimization Level to simulate production environment.
Is there any way to prevent this behaviour? To make/mark it "really retained" somehow?
So long as the application is "alive", they shouldn't be released, ever.
If your application is fully terminated (restarting simulator / closing it from the iPad), everything is released and when you open your app again you won't have anything.
Also, the point of a singleton is that you call a getter and it checks for its existence, and creates it if it doesn't, so there shouldn't be a problem if you don't have it at some point.
If you want persistent data when you re-launch your application, I suggest you look into serialization and/or some kind of persistence