Delve into Manage memory Essentials learning(3)

1Back in the good old days of iOS 3 and previous versions, the management of computer memory was a laborious affair(一件费力的事) as every pointer and memory allocation needed to be tracked precisely(精确地), lest(唯恐) you experienced the dreaded(可怕的) situation of memory leaks due to a missing release keycode in your code and so on. However, with the release of iOS 4 and higher, Apple introduced ARC and developers all over the world rejoiced(高兴庆祝) as they thought that the days of memory management were over. However, sadly, this is not the case as Objective-C is not like other programming languages such as Java or C#, where there is a garbage collector that will do the memory management and garbage(垃圾) collection for you. ARC only serves as an enabler(一个推送者) to simplify memory management for us so that we do not need to explicitly(明显地) call the release method such as [myArray release], since ARC handles these for us. So while there are less brain cells that we need to allocate for memory management when developing an iOS app, we must still do some basic memory management even with the introduction of ARC, and this chapter will help you along the way with that. So to get things off the ground, here are the topics that we will cover in this chapter 

2forgo(放弃)

3Memory overuse 

If you used enough iOS apps, you will notice that some apps will just force close(强制关闭) themselves after you innocuously(无害的无毒的) tap on a button or do some action. This is an iOS way of handling memory issues as it basically just says, "this app has a memory leak and you do not have enough memory to handle it, so this app has to be closed." 

内存过度使用就会被app关闭掉

4Step Into 

This will let your program follow the method into its own code and view() the code for the method 

5Step Out 

This will take you out of the current context and into calling a method one step up into the program stack 

6Breakpoints are very useful for checking the values of your variables at a specific point in time when your program is halted(停止) due to the breakpoint and the four icons for breakpoint debugging will aid you in debugging(调试) memory-related and other logic bugs. 

7Do note that a memory warning level does not necessarily mean that your application is leaking memory. (收到内存警告并不意味着内存泄漏)

8There could be a situation where your application is loading or performing operations on large resources such as data files, images, videos, and so on and this will trigger(引发) the memory warning. ARC will handle the cleaning up later. However, if you see a memory warning level 2, then you should start to look at your code as the next memory warning level will be the actual application crash. 

9Debugging(调试) crashes and memory leaks are like the game of hide and seek or playing detective. There will be a lot of clues(线索) lying around, which will lead you to the culprit(犯人) in your code that is causing a bothersome(麻烦的令人讨厌的) crash or memory leak. Apple has provided us with a lot of tools and logs, which will be useful for us in debugging our code. We will cover some of the commonly used methods here so that you can get cracking with(开始与) regards to fixing those problems as soon as possible. 

10One of the easier ways is to plug(插入) your device into your machine via your cable, fire up(煽动) Xcode, which will automatically detect(发现) your plugged-in(插入的) device and then press Shift + Command + C to activate(刺激) your debug console(后台), which is a black screen on the bottom right of your Xcode screen.

11However, there are occasions when you are testing your application, when it is not connected to your Xcode and it crashes at that moment. The preceding(在前的) method does not work in this case, so what can you do? Do not fret(烦恼), as there is another way to get your crash log once you are at your table and have plugged(堵塞) your iOS device into your machine and red up Xcode. 

12This will open your Organizer, which actually is a repository(仓库) of all the devices that have been connected to Xcode and shows information such as the application's provisioning profile and screenshots. However, what we are really interested in is the crash logs. So, click on the Devices button(OS button) at the top and you will be shown all the developer information about all the devices that have connected to your device so far. Click on your currently connected device, which is denoted by a green circle. Then, select the Device Logs option, which will then open another list of apps that have crashed. There you can sort(分类) the results by Process, which is the application name, Type, or Date/Time. Clicking on an item will reveal the crash log on the right side of the screen. There you can see the backtrace, which is actually a listing of all the methods that were called leading up to your crash. The last section of the code that caused your crash will be at the top of the backtrace, and you should start by looking from the bottom up to see how your app works and see all the functions and methods that it traversed(穿过) through leading up to the crash: (可以点击orgnizer可以找到)

13Plumbing(探究) memory leaks 

Objective-C and the C programming language are closely related as Objective-C is a proper superset(超集) of C, which means that anything that works in C will work with Objective-C(oc是c的超集,适合c的也一定适合oc).So inherently(内在的), it also means that memory management methods and protocols that you are familiar with in C or C++ will also apply to Objective-C(适合c和c++内存管理方法也一定适合oc). However, a good thing about Objective-C is that the compiler does a lot of this memory management for you under the hood(在引擎下面). This means that you do not need to write too much code to handle memory management in Objective-C compared to C or C++. 

14With the release of Automatic Reference Counting (ARC) support in Xcode 4.2 and iOS 4 and 5 onwards, developers everywhere thought that their days of laborious(勤劳的) memory management are over, but make no mistake as you need to keep in mind that ARC is a compile time memory management mechanism, where the compiler will examine the source code and then add the retain and release messages into the compiled code. ARC is not the traditional garbage collection mechanism that Java and C# programmers are familiar with where garbage collection is done during runtime by the garbage collector. 

15If you have done some Java and C# programming and come from a Java or C# background, you should be familiar with getter and setter methods or you may also know them as accessors(存取器) and mutators(增变基因), respectively(分别的). They are a fundamental pillar(一个基本支柱) of good programming. Getters/setters or accessors/mutators, are also known as methods used in keeping the principle(原则) of encapsulation(封装包装) where member variables are made private to protect them from other code which could be potentially malicious(恶意的蓄意的), and the getter/setter acts as a gatekeeper(门卫) or intermediary between the private member variable and other code. Take a look at the following lines of code: 

16The preceding(前面的) two methods should not be unfamiliar to you from a Java or C# perspective. Getters and setters can be considered bad if used improperly. Making a variable public and yet writing a getter and setter method is a good example as this violates(违反) the concept of encapsulation. Now, getter and setter methods are a good foundation for recommended programming practices as they confer(授予) the following benefits and more: 

17、nonatomic:This property is not thread safe, but it is faster than atomic. (线程不安全,但比atomic)

18atomic This property is used for completeness(完整性) and will not allow bad things to happen if a different thread tries to access this object at some point in your code. However, it is slower than nonatomic due to additional bookkeeping overhead(薄记开销) required. (优点,线程安全,缺点较慢)

19strong This is used with ARC and helps by not letting you worry about the retain count of an object as it is autoreleased when you are done with it. In code that does not support ARC, it is a synonym(同义词) for the retain property. 不用担心他的持有数量,因为它会被自动释放。是retain的同义词 

20Next, you will use the @synthesize keyword. The @synthesize keyword will tell the compiler, "Now that I have declared the property nonatomic and retain for my NSString *text object, please create the code now for the getter and setter pair of methods for my NSString *text object." (告诉编译器现在创建getter和setter方法)

21@synthesize 这个关键字在Xcode4.4后就会变成默认的

22Once the variable is synthesized, an instance variable (or iVar for short) is automatically created and prefaced(以…开始) with an underscore(下划线). The presence of this underscore in a variable name is a naming convention to indicate that this is an iVar, and this is done automatically for you within Objective-C. 

 So, this is why there is no compiler error when you call _myInt as _myInt is automatically created for you by the compiler when you tell the compiler the properties of what myInt will do. 

23@synthesize will also create the validation(批准) rules, which you assign to a variable using your @property keyword. Validation rules such as readonly means that when you try to assign a value to your variable, you will get a compiler error read only property cannot be reassigned, and that is the validation rule of your automatically created setter (mutator) method at work without the writing of verbose code. (它是创建setter和getter方法的批准)

24However, in some specific cases, you may want to override the default getter and setter methods that Xcode provides. Doing so is very easy, and using our int age as an example, we just create the following methods in our UserObject .h header file: 

       -(void) setAge:(int)aAge;

      -(int) getAge;

25We put in our custom getter and setter methods in our .m, UserObject implementation file as follows: 

      -(void) setAge:(int)aAge;

      {           int MIN_AGE = 20;//add in our validation logic for our       setter here

           if (aAge < MIN_AGE)

               age = 20;

           else

               age = aAge;

       -(int) getAge

       }

return age; } 26、运行时首先找自己类的方法,然后再找父类的方法,如果祖先没有方法,在看异类有没有方法,通过一系列的寻找过程,如果还没有找到,就直接报错,报unreccognized这个错误。 

27Although iOS devices such as iPhones and iPads have a lot of memory compared to the early Nokia phones, it does not mean that you can be sloppy(草率的) with regards to memory management 

28The iOS memory model and other mobile OSes do not include disk swap space(磁盘交换空间), which are present on computer OSes, where persistent storage space is used as an extension of the memory space so that persistent storage can be used as a form of RAM for situations where low memory is encountered. 

So, the apps that you develop for iOS devices are more limited in the amount of memory that you can access. (不像os系统,持久的存取空间被用来作为内存空间的一个延伸,以致持久的空间在低内存发生的时候能被用来作为内存的一种形式)

29、Using large amounts of memory will lead to a serious degradation(下降) of system performance and triggering(触发) of the three memory warning levels(三级内存警告水平), where the last warning level will lead to your application crashing. 

30Plus, apps running under multitasking(多任务) will share system memory with all other running apps that have higher priority such as the SMS application and phone application. So, you will never have 100 percent of the phone memory available for your application under any circumstance and even a brand new iOS device will have background processes running. So, reducing the amount of memory used by your iOS app should be a high priority task and not something that should be led under a low priority tag. SMS application and phone application优先级很高)

31、If there is less free memory available in your device, that means the system will have a higher probability of being unable to ful ll future memory requests. If such a situation was to occur, the system will remove suspected(被怀疑的) apps and nonvolatile(非易失性的) resources from memory. However, this is not a good solution as this is only temporary and those suspended apps and nonvolatile resources may be needed again a short while later. (当系统内存不足的时候,系统会杀掉一些被怀疑的app和移除一些非易失性的资源,但这是临时性的,这么做,其中有些app和资源可能会很短时间再次使用,但你把它删了)

32、To get down to a class level, you can register your object to receive the UIApplicationDidReceiveMemoryWarningNotification notification via the addObserver method to call a specific method once the memory is running low, as shown here: 

       [[NSNotificationCenter defaultCenter] addObserver:self

       selector:@selector(seeMemoryWarning:) name:

       UIApplicationDidReceiveMemoryWarningNotification

       object:nil];

       - (void) seeMemoryWarning:(NSNotification *)notification

       {

         NSLog(@"Low memory");

       }

可以通过这样获取内存警告,除了applicationDidReceiveMemoryWarning 这个方法外

33Once you see any of these warnings triggered in your code, you should respond immediately by looking at how you can write the code to free up any unwanted memory. A few ways to do this can be: 

(1)Removing any views that are not visible to the user but are still loaded in memory by calling the removeFromSuperview method such as [myView removeFromSuperview]; 移除视图

(2) Releasing any images that are not on screen by setting them to nil 通过nil设置图片

(3) Purging(清除) any data structures that are not used by your code at this point in
time by calling the
release method 清除任何数据结构

34、Imagine that you have a memory leak in your application and the leak causing the crash only appears after using the application for 2 hours. So, if you wish to replicate the memory leak and trigger(引发) the crash in your code, you need to run the application for 2 hours each time to see the crash. This can be a time consuming task as you need to leave your app running, but thankfully, Xcode provides a way to trigger(引发) the memory warning without actually producing a memory leak, and this feature comes courtesy(恩惠) of the iOS simulator. You can click on Hardware | Simulate Memory Warning in order to trigger a memory warning so that you can write and test your memory cleanup code(测试你的内存清理代码) under the relevant memory warning method handler. (模拟器的作用还这么大)

35、don't overthink about memory management不要过度考虑内存管理

(1)You can try to make your resource files such as audio, images, and property lists as small as possible. To reduce the space occupied by property list files, you can use the NSPropertyListSerialization class while the free, open source command-line tool called Pngcrush can be used to compress PNG files as you can have savings of 20 percent or more depending on your PNG files (能用Pngcrush来压缩文件)

(2)Core Data is more than just a persistent storage framework. Core Data provides a memory efficient way of managing large data sets, and if you manipulate large structured data, using the Core Data persistent store or SQLite database as a data store as opposed to NSData or NSUserDefault will ensure that you can have efficient memory usage provided by Apple's own Core Data framework.使用core data或者数据库

(3)Resources should always be loaded when you need it, such as when you only need to see it on the device screen. This is called lazy loading, which we have seen in the previous chapter. You could be tempted to load all resources much in advance before you actually use it. However, this will actually mean that your resource is occupying memory when it is actually not being used at the current moment. So to optimize memory usage, always practice lazy loading. 懒加载

(4)Finally, this is a little-known tip that you can use in your Build Settings: you can add the -mthumb compiler flag to help reduce the size of your code by using 16-bit instructions(指令) instead of 32-bit instructions, which uses up less space and this can result in savings of up to 35 percent. However, one caveat(警告) is that if your iOS application floating point intensive(加强的) code and your application needs to support ARMv6 such as older generation iPod Touches and older iPhones, then the -mthumb option should not be used for your application(除非能支持ARMv6,否则就不能设置-mthumb选项). However, if your code is for ARMv7, then you can enable the -mthumb option in your Xcode project, which is enabled by default. 

kvokvc使用注意事项

36The removeObserver method will crash if you are not the observer for that key path, so keeping an exact track of(保持一个准确的轨迹) the properties that you are observing is a must. 如果观察的键不在能引起崩溃

37With a few more notifications, you will write a lot of if-else statements and you will be able to see how unwieldy(笨拙的) the code will be and many bad things such as crashes, bugs, and so on will appear, and this requires more debugging time. 

38KVO registering can crash your app if you do it multiple times. If you have a superclass that is observing the same parameter on the same object, the removeObserver method will be called twice and it would lead to a crash on the second time. (移除方法调用两次,能引起崩溃)

39KVO works in a wonderful and magical way in the same way as callbacks. Code utilizing(利用) callback can be painful to debug. So, I would recommend KVO usage if you have adequate (足够的)experience with KVO and start with small projects as the API documentation is sparse(稀疏的) and it can lead to debugging problems down the road if you are not well versed with KVO. 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值