Delve into Manage memory Essentials learning(1)

Manage memory


Restart device regularly

You should restart your phone at least once per day.

1、作者Gibson Tang 

2Since then, he has never stopped keeping pace with(跟上) technology, and after he coded his rst "Hello World" program, he has been hooked on(迷上) programming ever since. 

3Following his studies at Nanyang Polytechnic(南洋理工学院) and Singapore Institute of Management(新加坡管理学院)and serving a 6-year stint in the Republic of Singapore Navy (RSN)(新加坡海军共和国)

4he honed his development skills creating software and games for Yahoo! and other Fortune 500 companies 

5In 2010, he founded Azukisoft Pte Ltd(Azukisoft 航运有限公司) in Singapore to focus on mobile application development. 

6Since then, he has developed countless mobile applications and games for start-ups (初创公司)and big companies both in USA and Singapore. 

7Apart from programming, he indulges in(沉迷于) various hobbies such as soccer, computer games, and jogging in(慢跑) order to get his regular dose of Vitamin D and to see the sun once in a while. 

8Occasionally(偶尔的), he would be on Steam or Battle.net blowing off(吹掉) some steam by slaying monsters(杀死怪物) and killer robots after a day of programming.

9Managing memory is one of the toughest(最难的) problems we deal with in Objective-C. 

10These example code will demonstrate the fundamentals of programming and memory management as well as cover some aspects of iOS development such as Core Data 

11So, this book will help you become aware of memory management and how to implement this correctly and effectively while being aware of the bene ts at the same time. This tutorial-based(基于辅导的) book will actively demonstrate techniques for the implementation of memory management, showing the resultant(结果的,合成的) effects on performance and effective implementation  

12Apple suggests Objective-C as a main tool of development for their platform and strives to(努力) improve the product continuously 

13I must say that not all of Apple's attempts to improve Objective-C have been entirely(完全地) successful. Garbage collection is an example of ineffective memory management. It is deprecated since OS X Version 10.8 in favor of Automatic Reference Counting (ARC) and is scheduled to(定于) be removed in a future version of OS X 

14I have been working with Objective-C for years and C++ for even longer. Hence, memory management is not an alien concept to me(对我并不陌生) as I have been debugging(调试) and tracing(追踪) memory leaks for years in the course of my work at Azukisoft Pte Ltd. 

15At my job at Azukisoft Pte Ltd, I work mostly with Objective-C but with the occasional C++ thrown into the mix. And this is a very interesting combination, which will be highlighted in this book too. 

16In this book, you will find a number of text styles that distinguish(区分) between different kinds of information. Here are some examples of these styles and an explanation of their meaning. 

16Code words in text, database table names, folder names, lenames, file extensions, pathnames, dummy URLs, user input, and Twitter handles are shown as follows: "When you do a new, malloc, or alloc, what the operating system does is that it is giving your program a chunk of memory on the heap().”

17New terms and important words are shown in bold(粗体的)。

18、Words that you see on the screen, for example, in menus or dialog(会话) boxes, appear in the text like this: "In Xcode, go to the target Build Phases tab, open the Compile Sources group, and you will be able to see the source file list.

19Reader feedback is important for us as it helps us develop titles that you will really get the most out of.(充分利用)

20、If there is a topic that you have expertise(专门知识)in and you are interested in either writing or contributing to a book, see our author guide at www.packtpub.com/authors  (这篇文章介绍部分没弄完)

21、In this chapter, we will concern ourselves principally(主要地) with the core issues of the memory management problem as well as an Objective-C-based solution of it 

22We will look at the ownership and life cycle of the object. This basic idea is known as manual references counting, or Manual Retain Release (MRR), where you need to claim and relinquish ownership of every object 

23It defines an object's life cycle. And finally, we'll take a look deeper into NSObject for a better understanding of what's going on. 

24It does not matter what programming language is being used; the question of memory management always persists 

25、In general, it is a question of resource management that cannot be avoided because memory is always a limited resource. 

26The scripting(脚本) languages and Java, where memory management is handled by the virtual machine or application (where it is hidden from the code), are not always effective enough. 

27While it is easier for the programmer this way, it can have a negative impact on resources, since you don't have an absolute control of it and there are objects still "living" when we don't need them anymore, plus these "living" objects still occupy(占据) precious memory space, which can be used by other objects 

28Additionally, depending on what you ask, another opinion is that an automatic memory management is the only right way to go. 

29Every tool has it's use in the correct context and Objective-C memory management concept is quite effcient in terms of both time cost savings and resource saving. 

30The memory in Objective-C, is managed in a different way from some of the widespread languages such as C/C++, Java, or C#, which are typically taught in schools as it introduces new concepts such as object ownership 

31Memory management is crucial(重要的) for devices that run on a limited amount of memory such as mobile phones, smart watches, and so on, since effective memory management will allow you to squeeze(压榨) every ounce of(每盎司) performance needed to run effciently on these small devices, where memory is scarce(稀有的) on these devices. 

32The idea of object ownership abstraction(抽象) is simple—one entity is simply responsible for another and an entity(实体) has the ability to own an object. When an entity owns an object, the entity is responsible to free that object too 

33A common situation where you will see multiple object ownership is when you use arrays. Arrays are indexed lists of objects(对象索引的列表), and when an object is placed into an array, the array claims ownership of the object. So, if I create an object in the main function and then put that object into an array, both the main function and the array will claim ownership of the object and create a reference to it at the same time. Ownership and reference are different as an object references another object, which it does not own and both are responsible for cleaning up the object. The following code demonstrates this: 


34、Just like objects in the real world, Objective-C objects are created; they live, and then go away when the application is closed. This is how the object life cycle works. Obviously, arrays have to claim the ownership on the object and prevent it to be deleted in the release method called in the main function. 

数组不得声明对这个对象的拥有,阻止它被main函数调用的release方法删除

35、Forgetting to send a release message to an object before setting a pointer to point at something else will guarantee you a memory leak. In order to create an object before it's initiated, a chunk of the OS memory is allocated to store it. Also, if you send a release statement to an object, which was not previously sent, a retain statement is sent to the object. This will be considered as a premature deallocation(成熟的分配), where the memory previously allocated to it is not related to it anymore. (一个释放它,另一个持有它,没有新分配内存,还是以前的内存)

36、A lot of time is spent on debugging(调试) these issues, which can easily become very complex in large projects. If you don't follow some solid principles for memory management, you can often forget and quickly find yourself getting stuck for(陷入) hours checking every retain and release statement. Even worse is if you're going through someone else's code, and they mess things up(乱成一团). Going through to fix memory management issues in someone else's code can take forever(需要很长时间).

37 A memory leak is when your program loses track of(失去的) a piece of memory that was allocated and has forgotten to release it. The consequence is that the "leaked" memory will never be freed(释放的) by the program. When more memory is leaked after a certain point in time, there will be no more free memory and this will cause your application to crash. 

38Usually, this tends to happen when a piece of code does new, malloc, or alloc, but never does a corresponding "delete", "free", or "release" respectively(分别的).(做了创建,但是没做释放)

39、When you do new, malloc, or alloc, what the operating system does is that it is giving your program a chunk of memory on the heap. The OS says, "Here, take this memory address and have this block of memory on it." Thus, you need to create
a reference to that memory address (usually in the form of a pointer), depending on the OS, such as, "I'm done with this, it's not useful anymore" (by calling "free", "delete", or "release"). 

40Memory leaks happen when you throw away your pointer to that memory. If your program does not retain where your memory is allocated on the heap, how can you even free it? The following line of code shows an example of a memory leak if you never call the release method on it: 

   NSMutableString *str = [[NSMutableString alloc]

   initWithString:@"Leaky"];

【如果没有调用release方法,这块内存从来不被释放,但是NSMutableArray * arr = [NSMutableArray array]不会,因为这个方法里面加了一个autorelease】

41、So why should you care? At best, you're the dissipating(消散) memory that will be freed(释放的) when the user quits your app. At worst, there could be a memory leak that happens in every screen.

42It would not be a great mode to end up your program, especially
if the user lets it run for a long time. A program crash is very hard to debug as 

it can crash at random moments(任何时刻) in your application as memory leaks are very unpredictable(不可预测的) to replicate(复制) and creating an application that crashes often will lead to bad reviews of your program on the App Store, or through word of mouth(口碑营销), which is something that you do not want to happen. 

43In the early stage, Objective-C had a class called Object. This had a method called +new, which wrapped malloc(), and a method called -free. Since Objective-C objects were generally aliased(别名的) and managing object life cycles became quite complex, this was troublesome. 

44NSObject is used by NeXT—Steve Job's second company, founded after he was red from Apple in 1985 —in order to provide reference counting, thus, dividing Object pointers in two categories: pointers that own references and pointers that do not own references. (两种指针,有引用计数的,没引用计数的)

45Those pointers that contribute towards the object's reference count are owning reference pointers. 对引用计数做贡献的对象拥有引用的指针。

46If there is a certainty(确定) that a reference is going to be held(将被持有) somewhere else for the duration of a variable's lifetime, a non-owning reference pointer(非拥有的引用指针) can be used avoiding the additional overhead(开销) of reference count manipulation(操作) since a non-owning reference pointer does not have the added cost of keeping track of object ownership. (因为一个非拥有的引用指针没有增加追踪对象拥有关系的开销)

47、Non-owning reference pointers are often used for autoreleased values. Autorelease pools make it possible for a temporary object to receive a non-owning reference pointer in return(临时对象会收到一个非拥有的对象指针). An object, by receiving an -autorelease message is added to a list that will be deallocated afterwards(加进到以后会被释放的list中), with the destruction of the current autorelease pool. You can call autorelease using the autorelease method as shown here: [myObject autorelease];

48The autorelease method 

An object is sent a release message, but put in an autorelease pool and the object is released when the pool is drained later during the run loop, but still occupies memory (运行循环期间,这个池子就会被清倒,仍占用内存)

49、Using autorelease instead of the normal release method will extend the lifetime of an object until the pool is drained at the end of the run loop. (运行时的末端)

50、ARC:It forces the compiler to handle the memory management calls at compile time(编译的时间) instead of the conventional(通常的惯例的) garbage collection functionality, which occurs during runtime. ARC also adds some things to the language model in general. It has been supported since iOS5, OS X 10.7, and by GNUstep. 

51In Objective-C, protocols define a set of behaviors that an object is expected to conform to in certain situations at runtime. For example, a table view object is expected to be able to communicate with a certain data source so that the table view will know what data and information to display. Protocols and classes do not share the same namespaces(命名空间)(a set of identifiers containing names, the names of classes and protocols, thus the same name can exist in different namespaces). It's possible to have both, which are unrelated at the language level, but have the same name. This is the case with NSObject. 

53If you look at the language, there are no places where you can use either a protocol or a class name. Using class names as the target of message sends, as type names, and in @interface declarations is allowed. Likewise, it's possible to use protocols names in a few identical places; however, not in the same way. Having a protocol with the same name as a class won't result any issue. (协议和类名相同不会导致任何问题)

54It is impossible for root class to have a superclass as they are at the top of the hierarchy, so there is no superclass above a root class and NSObject class is one of them. And I give emphasis on(特别强调) saying one of them because in comparison to other programming languages in Objective-C, it's perfectly possible to have the existence of multiple root classes. (其他语言有多个根类)

55、Java's single root class is named java.lang.Object, which is the parent ultimate(最终的) class of any other. For this reason, any piece of code in Java, which comes from any object, has the basic methods added by java.lang.Object

56Cocoa can have multiple root classes. Besides NSObject, there is NSProxy and a few others root classes; and such root classes are, in part, the reason for the existence of the NSObject protocol. The NSObject protocol determines a specifc set of(一套具体的) basic methods, expecting their implementation by the others root classes(期盼这些方法在其他地方实现), consequently(因此), making those methods available whenever and wherever they are needed. 

57The NSObject class is in accordance to(根据) the NSObject protocol, which results in the implementation of this basic method

58Methods such as hash, description, isEqual, isKindOfClass, isProxy, and others are found in the NSObject protocol. NSProxy to NSObject protocol denotes that(表示) implementing the basic NSObject methods, it's still possible to count on NSProxy instances. 

59Subclassing NSObject would pull in a lot of baggage(行李) that may cause a problem. NSProxy assists(帮助) in order to prevent this by giving you a simpler superclass that doesn't have so much extra stuff(东西) in it.

60The fact that the NSObject protocol is useful for root classes isn't all that interesting for most Objective-C programming, for the simple fact that we don't make use of other root classes frequently. However, it will be very convenient when you need to make your own protocols. 

61In general, you can't ask it to do any of the stuff that a normal object can do. There are times when this doesn't have any importance(一点都不重要), but in some circumstances(在一些情形), you will wish to be able to perform this task. 

62As mentioned earlier, NSObject, the root class of most Objective-C class hierarchies and through NSObjects, your Objective-C classes can inherit an interface to the system and also gain the ability to behave as Objective-C objects. So, NSObject is important if you want your objects to gain access to(接近) methods such as isEqual, so on, and so forth. This is where the NSObject protocol comes into the picture. Protocols can inherit from other protocols, which means that MyProtocol can inherit from the NSObject protocol: 

 @protocol MyOwnProtocol <NSObject>

       - (void)myFunction;

       @end

63This says that not only do objects that conform to MyOwnProtocol respond to myFunction, but they also respond to all those common messages in the NSObject protocol. Knowing that any object in your application directly or indirectly inherits from the NSObject class, that it's in accordance to(根据) the NSObject protocol, there is no imposition(没有实施) to any additional requirements on people implementing MyOwnProtocol, while giving you the permission to use these basic methods on instances. 

64The fact that there are two different NSObjects is abnormal for the frameworks; however, it starts to make sense when you go deeper into it. The NSObject protocol grants the permission to all root classes that have the same basic methods, making, also, a very easy way to declare a protocol that also includes basic functionality expected from any object. The NSObject class introduces it all together, since it's
in accordance to the
NSObject protocol. One thing to note here is that a custom class that's created and does not inherit NSObject can be considered as a root class, but once you make your custom class inherit from NSObject, then the root class won't be your custom class anymore, and the root class will be NSObject. However, generally, most of your custom classes should inherit from NSObjects; it will implement NSObject's functionality such as alloc, init, release, and so on and without inheriting from NSObject, these functionalities need to be written and implemented by you. 

ARC (第二章)

1In this chapter, you learned what memory management in Objective-C is and how
it works. You also learned the best practices while working with Manual Retain Release, and got an introduction to Automatic Reference Counting, Objective-C Objects, and root classes. ARC basically can be considered as a compile time guard against(
防范) memory leaks as the compiler will automatically write the release statements for you at compile time(arc 基本上被考虑在编译时间防范内存泄漏,因为编译器将自动的写释放声明 ). So, there is no need to write verbose(冗长的啰嗦的) release statements in your code to keep it clean and terse(简洁的).

2Good ideas live a long life and bad ones die fast(好主意获得久,但是坏主意死的快). In Objective-C, reference counting's long life was seen as a very good idea. The next step of evolution in this is that it became automatic, so we call it Automatic Reference Counting (ARC), which was introduced by Apple Inc. in 2011 for application development on its desktop and mobile OS, Mac OS X Lion, and iOS 5. It changed the name of the initial referencing counting to Manual Reference Counting.

3Garbage collection is only available for Mac OS X, starting with version 10.5. Also, note that iOS applications can't use Garbage collection; since it relies on(依赖) the power of the device, it will take some time to process(处理), forcing the user to wait the process end, thus producing a bad user experience(一个差的用户体验). It is also deprecated since OS X Version 10.8 is in favor of ARC and is scheduled to be removed in the forthcoming versions of OS X 也被移除

4ARC is a new and innovative(革命性的) way that contains many of the Garbage collection's advantages, yet different from Garbage collection. ARC does not have any process in the background to make the object's deallocation, which gives ARC a big advantage against Garbage collection when comparing their performance 

5 ARC does not impose(利用) a runtime memory model(运行时内存模型) as Garbage collection does. Code compiled under ARC uses the same memory model as plain C or non- ARC Objective-C code, and can be linked to the same libraries. 

ARC only makes automatic memory management possible for Objective-C objects, inherited from NSObject (note that(注意) in Objective-C, blocks also happen to be objects under the covers though(block 在后台也是对象)).
Memory allocated in any other way is not touched and must still be managed manually. The same goes for other resources such as file handles and sockets, such as streams. 

以其他方式生成的内存不被触及,必须被手动管理,比如文件处理,或者比如流。

6、At its core(核心处), ARC is not a runtime service; it doesn't work on program execution(ARC不是一个运行时服务,它不在项目执行时工作,不像垃圾收集装置做的一样), as Garbage collection does. On the other hand, the new Clang, the compiler frontend(前端) for C, C++, Objective-C, and Objective-C++, provides it as a two-part phase(两个阶段) (we will call these phases "cycles"). In the following diagram(), you can see these two phases. At the cycle named frontend as shown in the following diagram, Clang will analyze every preprocessed file for properties and objects. And then, relying on a few fixed rules, it will insert the correct statements—retain, release, and autorelease

 

7For instance, if an object is allocated and locally(在本地) corresponds to a method, this object will have a release statement close to that method's endpoint(在那个方法的末端). This release statement, if it is a class property, comes into(进入) the dealloc method in a class, which can be your custom class or any Objective-C class. If it's a collection object or a return value, it will get an autorelease statement. However, if it was referenced as weak, it will be left in peace.(如果是一个弱的类型,这个对象不会被处理,待在那里)

8、The frontend also inserts retain statements for disowned objects(非拥有对象) locally(本地的). It goes to every declared accessor(访问器) and updates them with the directive(指令) @property. It includes calls to the dealloc routine of their superclasses such as NSObject or UIViewController or even your own customer superclass(自己定制的超类). It will also report any explicit(显式的) management call and double ownership. 

In the optimize cycle, the modified(修改的)  sources are sent to load balancing by Clang.
So, it calculates the retain and release calls created for each object, and reduces all to the optimal(
最优的) minimum. This action avoids excessive(过度的) retain and release messages with the possibility to impact(影响) with full performance (避免影响性能)

9、属性前面的strong ,weak等字节是属性的释放规则,CLang会根据属性声明的特征,来进行自动释放

10、Sending a release statement to the myOwnString property (line 24) is the responsibility of one of them. The other sends a retain message to the myString argument (line 25). Before returning the last one as its result, the getMyBar function sends locally a autorelease statement to the yBar local. Lastly, MRC supersedes(替代) the dealloc method of that class. MRC also releases the myOwnString property (line 44) and invokes the dealloc method of its superclass (line 45); still in that method, if there is already a dealloc method, MRC properly updates its code. 

11A very significant improvement in Objective C 2.0 is its memory model. The countless(无数的) remnants(残余) of problems from the first Objective-C implementations as a preprocessor(处理器) that induced(感应) C were cleaned up. In older versions, Objective-C objects were simply C structures, containing a pointer to their classes in their first fields, and its pointers were just able to receive messages when you wanted to send them. 

一个在2.0非常有意义的改进是内存模型

12、Now every object pointer comes into one of the following categories: weak, strong, autoreleasing, and unsafe unretained. When ARC is disabled, the programmer is responsible to take care of them all, being sure that they are all safe, for the reason that all those pointers just fit the last category.

现在每一个对象指针进化为下面策略(weak 、strong 、autoreleasing以及unsafe unretained)之一,当ARC使用之前,程序员负责照顾所有.....

13、The default category (type qualifier) is a strong pointer; they are largely correspondent to the consequences of writing flawless(完美的) defensive(防御用的) retain/release code. Assigning to a strong pointer is relative to retain the new value and release the old value, because owning references are stored in those pointers. 

默认的类型是一个强指针

14、You need to use autoreleasing pointers in order to store values that are autoreleased. In Objective-C, such pointers are the most habitual(习惯的) form of non- owning reference pointers; they are variables on the heap storing autoreleased values. An owning reference pointer, also known as an instance variable, will only be autoreleased when it is stored to a non-owning reference pointer, known as an autoreleasing variable. If you simply store an autoreleased reference pointer, you will have a simple attribution. 

15In order to decrease the quantity of release and retain statements in a crucial(重要的) piece of code, it's possible to make use of _autoreleasing, one of the four ARC type qualifiers(限定符). However, since the objects will be included in the autoreleasing pool and ARC can commonly eliminate(消除) this, it's usually not required to use this type qualifier, besides the fact that is can make things slower. 

16Weak is the last category (type qualifier) of pointer. If you used the garbage-collector mode(模式) in Objective-C, you probably already met weak pointers by storing an object in such a pointer. It's not seen as an owning reference pointer (for instance, a variable), and when the object is deallocated, this point is immediately set to nil. 

17We can count many differences between GC and ARC mode, but the very important one is about ARC being deterministic(确定性的). It's possible to see it through weak pointers. See the following code for an example: 

       id strong = [NSObject new];

       __weak id weak = strong;

       strong = nil;

       NSLog(@"%@", weak);

18Even using ARC, we are still free to use autorelease messages to drain/create our pool at any time. It doesn't affect the compiler when implementing retain and release messages, but provides hints(暗示) when it's safe to make autoreleased objects go out of scope. 

即使使用ARC,我们也可以使用autorelease ,但是在作用域之外使用autoreleased

19Note that I really meant "without worrying so much", not "without worrying at all" because even with these handy(便捷的) frameworks that create and clear the object for you, there will be cases when you want to take more control and create additional autorelease pools yourself. 还是有情况,要你采用更多的控制和创建额外的自动释放池。

20The NSAutoreleasePool class is used to support Cocoa's reference-counted memory management system. 

自动释放池支持引用计数框架系统。

21If a program references the NSAutoreleasePool class while in ARC mode, it's considered invalid and is rejected in the build phase. Instead, in ARC mode, you need to replace it with @autoreleasepool blocks, thus defining a region where an autorelease pool is valid, as you can see in the following code: (必须用@autoreleasepool,否则就会被认为是无效的,在build阶段会被拒绝,

22、Even if you don't use ARC, you can take advantage of @autoreleasepool blocks 

that are far more effective than the NSAutoreleasePool class. (@autoreleasepool 比pool class 更高效)

22、This NSAutoreleasePool class is like a collection of these objects and goes one by one(一个接一个) sending a release message when it's drained(倒掉)(drain也是一个方法)

23By using an autorelease as an alternative to a release message, you extend the object's lifetime, this time maybe even longer if the object is later retained or at least until the NSAutoreleasePool class is drained. If you put an object into the same pool more than once, for each time, it will receive a release message. (通过自动释放池,延长了对象的寿命,时间可能更长,这个对象以后可能还会重新被retain或者至少直到NSAutoreleasePool被倾泻,如果一个对象被放进池子超过一次,那他就会收到多条释放消息)

24While into an environment with reference counting, Cocoa presumes(假定) there will always be an autorelease pool available; otherwise, objects that have received an autorelease message won't get released. This practice will leak memory and generate(产生) proper warning messages. (如果没有自动释放池,这么做将会产生内存泄漏,产生合适的警告信息)

25At the beginning of a cycle of the event loop, an autorelease pool is created by the Application Kit (one of the Cocoa frameworks, also known as AppKit). It(指AppKit) provides code to create and interact with(交互) GUI, and it's drained at the end of this cycle, then every autoreleased object created when processing an event is just released(然后就是在程序处理中创建的每个自动释放的对象被释放). It means you don't need to create the pools yourself as the Application Kit does it for you. However, if there are many autoreleased objects created by your application, you should consider the creation of "local" autorelease pools; this is an advantage to avoid the peak memory footprint (然而,你的应用创建了很多自动释放的对象,你应该考虑很多本地自动的创建,以避免内存泄漏)

26、To create an NSAutoreleasePool object, you can use the regular alloc and init methods and use drain to dismiss it. A pool cannot be retained(不能被持有); the consequences of drain is like a deallocation, and it's very important to do so in the same context you created it. 

27Every thread has its own stack of autorelease pools. These stacks contain NSAutoreleasePool objects, which in turn contain autoreleased objects. Every new autoreleased object is placed on the top of the pool and every new pool is placed on the top of the stack.(每个新的自动释放对象被放到池子的顶部,每个新的池子被放到stack的顶部) A pool is removed from a stack when it's drained. Before a thread is finished, it drains every autorelease pool on its stack (一个线程被完成前,它释放在stack顶部的每一个池子)

28Despite the fact that an autorelease pool can be manually created and objects can be manually added to it, ARC still drains the pool automatically: you're not allowed to do it yourself. (不被允许,这是为什么,这里说明的是NSAutoreleasePool初始化,以及添加要释放的对象机器已经被去掉了,转而变成@autoreleasepool方式

29、To ensure that you don't have to worry about ownership, this is what ARC does: easily create autorelease pools, and make them temporarily handle the holding and releasing of autoreleased objects for you. 

确保你不担心这个拥有关系,ARC做的事:很容易的创建池子,使得这些池子临时地处理自动释放对象的持有和释放。

30、Objects that were created inside the block receive a release message when the block is terminated. An object receives release messages as many times as it receives an autorelease message inside the block. 

31If an autorelease message is not sent inside the autorelease pool block, Cocoa will return error messages and your application will leak memory. You generally don't need to create your own autorelease pool blocks, but there are three situations where you will be required to: (你通常不需要创建你自己的自动释放池代码块,但是下面的三种情形你需要强制做的)

While creating a program that is not based on UI, such as a command-line one 你的项目不是基于ui,而是基于命令行

While creating a loop that generates a large number of temporary objects 当创建一个循环的时候,你创建了很多的临时对象

When a secondary thread has to be created 当另外一个线程不得不被创建的时候

32Memory footprint is basically the primary amount of memory used by a program in runtime. Temporary autoreleased objects are created in countless applications, and they add to the

application's memory footprint until the block is ended. Allowing this accumulation(消耗) until the current event loop finally ends, in some cases, may result in an exorbitant overhead(过分的开销)

and you might want to quickly get rid of those temporary objects; after all, they are highly adding to the memory footprint. In this case, the creation of your own "local" autorelease pool blocks is

solution. In the end, all objects are released, consequently deallocated, beneficially reducing the memory footprint. 

33 NSArray *myUrls = <# Sample Array of URLs #>;

   for (NSURL *url in myUrls) {

     @autoreleasepool {
   /* Two objects are created inside this pool:

   NSString "contents", NSError "error"

   At the end of the pool, they are released. *

    NSError *error;         

    NSString *contents = [NSString    

    stringWithContentsOfURL:url

           encoding:NSUTF8StringEncoding error:&error];
            /* Here you can process the NSString contents,

       thus creating and autoreleasing more objects. */

       }

34As it was said before, the Cocoa framework provides factory methods(工厂方法) with autorelease for many of the basic classes such as NSString, NSArray, NSDictionary, NSColor, and NSDate 

35、我们对app的任何操作到操作的结束都可以认为是一个事件。

 

36While using NSRunLoop, at the beginning of every run loop, an autorelease pool
will be created, and it will only be destroyed at the end of this run loop. To clarify, every temporary object created inside it will be deallocated at the end of the running iteration(
迭代). It might not be beneficial(有益的) if you are creating a large number of temporary objects inside the block; in this case, you should consider creating a new autorelease pool, as shown here 

37Notice that in order to end the autorelease pool, instead of sending a release message, we sent a drain message. It was done this way because in garbage collector mode, Objective-C runtime will simply ignore release messages, while the drain message won't be ignored, providing a hint(暗示) to the collector; however, it doesn't destroy the autorelease pool. (注意这里不是release而是drain,它不毁坏自动释放池

38、Application Kit creates an autorelease pool in the main thread at the beginning of each iteration, event, and releases it at the end of each iteration, thus exempting(免除) all autorelease objects created during the processing of the event. (在迭代的末尾才释放,免得在事件处理的程序中创建的很多对象被释放)

39、Basically, the run loop in iOS waits for the complete execution of an event until the application does something else. These events can be touchscreen interactions(触屏交互), incoming calls(电话), and so on.

40For each iOS event handling, a new autorelease pool is created at the beginning and released (drained) when the event's processing is completed. Theoretically(理论上讲), it can be any number of nested autorelease pools(任何数量的释放池), but remember they are created at the beginning of the event's processing (但是记住这些是在事件处理的开头)

41、NSException 异常

Exceptions may happen, and if they do occur, autorelease pools are automatically cleaned up after them. Autorelease pools prove to be a handful(一些) tool in order to write exception-safe code. 

42Despite the fact that ARC does a good job handling the memory management for us, there is still a situation when you need to use autorelease. Sometimes, we create a large number of temporary objects and many of them are only used once. In this case, you might want to free up the memory used by them. (有时,我们创建了大量的临时地对象,他们中的许多只被使用一次,这种情况下,你也许需要用autorealease来释放它)

43、 /*

     -------------------------------------------------------

     Non-ARC Environment with Memory Leaks

   */

   @autoreleasepool

   {

     // No autorelease call here

      MyObject *obj = [[MyObject alloc] init];

      /* Since MyObject is never released its

        a leak even when the pool exits

*/ } 

44  /*

     -------------------------------------------------------

     Non-ARC Environment with NO Memory Leaks

   */

   @autoreleasepool

   {

     // Memory is freed once the block ends

     MyObject *obj = [[[MyObject alloc] init] autorelease];

   }

45 /*

     -------------------------------------------------------

     ARC Environment

*/

@autoreleasepool

{ 

 MyObject *obj = [[MyObject alloc] init];

/*

   No need to do anything once the obj variable

   is out of scope. There are no strong pointers

   so the memory will be free


*/ } 

46  ARC Environment

   */

   MyObject *obj; // Strong pointer from elsewhere in scope

   @autoreleasepool

   {

       obj = [[MyObject alloc] init];

       // Not freed still has a strong pointer

   }

47You will need to create your own autorelease pool if you are making Cocoa calls outside the main thread of the Application Kit. It may happen that you create a foundation-only application for example, or separate a thread. 

如果你在App Kit外调用了Cocoa Calls,你也许需要创建你自己的单独的释放池,它也许发生在你创建了一个纯FOUNDATION应用,或者单独起了一个线程。

48、If your application generates a large number of autoreleased objects, instead
of maintaining a single autorelease pool, you are highly advised to drain the autorelease pool and create a new one frequently(
频繁地). This behavior is used by Application Kit on the main thread(这个行为尤其在主线程使用Application Kit的时候). If you neglect(忽视) this, your autoreleased objects don't deallocate, growing the memory footprint. On the other hand, if your thread doesn't make Cocoa calls, you can easily ignore this advice.

原书名:Objective-C-Memory-Management-Essentials

Restart device regularly

You should restart your phone at least once per day.

1、作者Gibson Tang  

2Since then, he has never stopped keeping pace with(跟上) technology, and after he coded his rst "Hello World" program, he has been hooked on(迷上) programming ever since. 

3Following his studies at Nanyang Polytechnic(南洋理工学院) and Singapore Institute of Management(新加坡管理学院)and serving a 6-year stint in the Republic of Singapore Navy (RSN)(新加坡海军共和国)

4he honed his development skills creating software and games for Yahoo! and other Fortune 500 companies 

5In 2010, he founded Azukisoft Pte Ltd(Azukisoft航运有限公司) in Singapore to focus on mobile application development. 

6Since then, he has developed countless mobile applications and games for start-ups (初创公司)and big companies both in USA and Singapore. 

7Apart from programming, he indulges in(沉迷于) various hobbies such as soccer, computer games, and jogging in(慢跑) order to get his regular dose of Vitamin D and to see the sun once in a while. 

8Occasionally(偶尔的), he would be on Steam orBattle.netblowing off(吹掉) some steam by slaying monsters(杀死怪物) and killer robots after a day of programming.

9Managing memory is one of the toughest problems we deal with in Objective-C. 

10These example code will demonstrate the fundamentals of programming and memory management as well as cover some aspects of iOS development such as Core Data 

11So, this book will help you become aware of memory management and how to implement this correctly and effectively while being aware of the bene ts at the same time. This tutorial-based(基于辅导的) book will actively demonstrate techniques for the implementation of memory management, showing the resultant(结果的合成的) effects on performance and effective implementation 

12Apple suggests Objective-C as a main tool of development for their platform and strives to(努力) improve the product continuously 

13I must say that not all of Apple's attempts to improve Objective-C have been entirely(完全地) successful. Garbage collection is an example of ineffective memory management. It is deprecated since OS X Version 10.8 in favor of Automatic Reference Counting (ARC) and is scheduled to(定于) be removed in a future version of OS X 

14I have been working with Objective-C for years and C++ for even longer. Hence, memory management is not an alien concept to me(对我并不陌生) as I have been debugging(调试) and tracing(追踪) memory leaks for years in the course of my work at Azukisoft Pte Ltd. 

15At my job at Azukisoft Pte Ltd, I work mostly with Objective-C but with the occasional C++ thrown into the mix. And this is a very interesting combination, which will be highlighted in this book too. 

16In this book, you will nd a number of text styles that distinguish(区分) between different kinds of information. Here are some examples of these styles and an explanation of their meaning. 

16Code words in text, database table names, folder names, lenames, le extensions, pathnames, dummy URLs, user input, and Twitter handles are shown as follows: "When you do anew,malloc, oralloc, what the operating system does is that it is giving your program a chunk of memory on the heap().”

17New termsandimportant words are shown in bold(粗体的)。

18、Words that you see on the screen, for example, in menus or dialog(会话) boxes, appear in the text like this: "In Xcode, go to the targetBuild Phasestab, open the Compile Sources group, and you will be able to see the source file list.

19Reader feedback is important for us as it helps us develop titles that you will really get the most out of.(充分利用)

20、If there is a topic that you have expertise(专门知识)in and you are interested in either writing or contributing to a book, see our author guide atwww.packtpub.com/authors (这篇文章介绍部分没弄完)

21、In this chapter, we will concern ourselves principally(主要地) with the core issues of the memory management problem as well as an Objective-C-based solution of it 

22We will look at the ownership and life cycle of the object. This basic idea is known as manual references counting, orManual Retain Release(MRR), where you need to claim and relinquish ownership of every object 

23It defines an object's life cycle. And finally, we'll take a look deeper intoNSObjectfor a better understanding of what's going on. 

24It does not matter what programming language is being used; the question of memory management always persists 

25、In general, it is a question of resource management that cannot be avoided because memory is always a limited resource. 

26The scripting(脚本) languages and Java, where memory management is handled by the virtual machine or application (where it is hidden from the code), are not always effective enough. 

27While it is easier for the programmer this way, it can have a negative impact on resources, since you don't have an absolute control of it and there are objects still "living" when we don't need them anymore, plus these "living" objects still occupy(占据) precious memory space, which can be used by other objects 

28Additionally, depending on what you ask, another opinion is that an automatic memory management is the only right way to go. 

29Every tool has it's use in the correct context and Objective-C memory management concept is quite effcient in terms of both time cost savings and resource saving. 

30The memory in Objective-C, is managed in a different way from some of the widespread languages such as C/C++, Java, or C#, which are typically taught in schools as it introduces new concepts such as object ownership 

31Memory management is crucial(重要的) for devices that run on a limited amount of memory such as mobile phones, smart watches, and so on, since effective memory management will allow you to squeeze(压榨) every ounce of(每盎司) performance needed to run effciently on these small devices, where memory is scarce(稀有的) on these devices. 

32The idea of object ownership abstraction(抽象) is simple—one entity is simply responsible for another and an entity(实体) has the ability to own an object. When an entity owns an object, the entity is responsible to free that object too 

33A common situation where you will see multiple object ownership is when you use arrays. Arrays are indexed lists of objects(对象索引的列表), and when an object is placed into an array, the array claims ownership of the object. So, if I create an object in the main function and then put that object into an array, both the main function and the array will claim ownership of the object and create a reference to it at the same time. Ownership and reference are different as an object references another object, which it does not own and both are responsible for cleaning up the object. The following code demonstrates this: 


34、Just like objects in the real world, Objective-C objects are created; they live, and then go away when the application is closed. This is how the object life cycle works. Obviously, arrays have to claim the ownership on the object and prevent it to be deleted in the release method called in the main function. 

数组不得声明对这个对象的拥有,阻止它被main函数调用的release方法删除

35、Forgetting to send a release message to an object before setting a pointer to point at something else will guarantee you a memory leak. In order to create an object before it's initiated, a chunk of the OS memory is allocated to store it. Also, if you send a releasestatement to an object, which was not previously sent, aretain statement is sent to the object. This will be considered as apremature deallocation(成熟的分配), where the memory previously allocated to it is not related to it anymore.(一个释放它,另一个持有它,没有新分配内存,还是以前的内存)

36、A lot of time is spent on debugging(调试) these issues, which can easily become very complex in large projects. If you don't follow some solid principles for memory management, you can often forget and quickly nd yourself getting stuck for(陷入) hours checking every retain and release statement. Even worse is if you're going through someone else's code, and they mess things up(乱成一团). Going through to fix memory management issues in someone else's code can take forever(需要很长时间).

37 A memory leak is when your program loses track of(失去的) a piece of memory that was allocated and has forgotten to release it. The consequence is that the "leaked" memory will never be freed(释放的) by the program. When more memory is leaked after a certain point in time, there will be no more free memory and this will cause your application to crash. 

38Usually, this tends to happen when a piece of code doesnew,malloc, oralloc, but never does a corresponding "delete", "free", or "release" respectively(分别的).(做了创建,但是没做释放)

39、When you do new,malloc, oralloc, what the operating system does is that it is giving your program a chunk of memory on the heap. The OS says, "Here, take this memory address and have this block of memory on it." Thus, you need to create
a reference to that memory address (usually in the form of a pointer), depending on the OS, such as, "I'm done with this, it's not useful anymore" (by calling "free", "delete", or "release"). 

40Memory leaks happen when you throw away your pointer to that memory. If your program does not retain where your memory is allocated on the heap, how can you even free it? The following line of code shows an example of a memory leak if you never call the release method on it: 

   NSMutableString *str = [[NSMutableString alloc]

   initWithString:@"Leaky"];

【如果没有调用release方法,这块内存从来不被释放,但是NSMutableArray * arr = [NSMutableArray array]不会,因为这个方法里面加了一个autorelease】

41、So why should you care? At best, you're the dissipating(消散) memory that will be freed(释放的) when the user quits your app. At worst, there could be a memory leak that happens in every screen.

42It would not be a great mode to end up your program, especially
if the user lets it run for a long time. A program crash is very hard to debug as 

it can crash at random moments(任何时刻) in your application as memory leaks are very unpredictable(不可预测的) to replicate(复制) and creating an application that crashes often will lead to bad reviews of your program on the App Store, or through word of mouth(口碑营销), which is something that you do not want to happen. 

43In the early stage, Objective-C had a class calledObject. This had a method called+new, which wrapped malloc(), and a method called-free. Since Objective-C objects were generally aliased(别名的) and managing object life cycles became quite complex, this was troublesome. 

44NSObject is used by NeXT—Steve Job's second company, founded after he was red from Apple in 1985 —in order to provide reference counting, thus, dividing Object pointers in two categories: pointers that own references and pointers that do not own references.(两种指针,有引用计数的,没引用计数的)

45Those pointers that contribute towards the object's reference count are owning reference pointers.对引用计数做贡献的对象拥有引用的指针。

46If there is a certainty(确定) that a reference is going to be held(将被持有) somewhere else for the duration of a variable's lifetime, a non-owning reference pointer(非拥有的引用指针) can be used avoiding the additional overhead(开销) of reference count manipulation(操作) since a non-owning reference pointer does not have the added cost of keeping track of object ownership.(因为一个非拥有的引用指针没有增加追踪对象拥有关系的开销)

47、Non-owning reference pointers are often used for autoreleased values. Autorelease pools make it possible for a temporary object to receive a non-owning reference pointer in return(临时对象会收到一个非拥有的对象指针). An object, by receiving an -autorelease message is added to a list that will be deallocated afterwards(加进到以后会被释放的list中), with the destruction of the current autorelease pool. You can call autorelease using the autorelease method as shown here: [myObject autorelease];

48The autorelease method 

An object is sent a release message, but put in an autorelease pool and the object is released when the pool is drained later during the run loop, but still occupies memory(运行循环期间,这个池子就会被清倒,仍占用内存)

49、Using autorelease instead of the normal release method will extend the lifetime of an object until the pool is drained at the end of the run loop. (运行时的末端)

50、ARC:It forces the compiler to handle the memory management calls at compile time(编译的时间) instead of the conventional(通常的惯例的) garbage collection functionality, which occurs during runtime. ARC also adds some things to the language model in general. It has been supported since iOS5, OS X 10.7, and by GNUstep. 

51In Objective-C, protocols define a set of behaviors that an object is expected to conform to in certain situations at runtime. For example, a table view object is expected to be able to communicate with a certain data source so that the table view will know what data and information to display. Protocols and classes do not share the same namespaces(命名空间)(a set of identifiers containing names, the names of classes and protocols, thus the same name can exist in different namespaces). It's possible to have both, which are unrelated at the language level, but have the same name. This is the case with NSObject. 

52If you look at the language, there are no places where you can use either a protocol or a class name. Using class names as the target of message sends, as type names, and in@interfacedeclarations is allowed. Likewise, it's possible to use protocols names in a few identical places; however, not in the same way. Having a protocol with the same name as a class won't result any issue. 

53If you look at the language, there are no places where you can use either a protocol or a class name. Using class names as the target of message sends, as type names, and in@interfacedeclarations is allowed. Likewise, it's possible to use protocols names in a few identical places; however, not in the same way. Having a protocol with the same name as a class won't result any issue. (协议和类名相同不会导致任何问题)

54It is impossible for root class to have a superclass as they are at the top of the hierarchy, so there is no superclass above a root class and NSObject class is one of them. And I give emphasis on(特别强调) sayingone of thembecause in comparison to other programming languages in Objective-C, it's perfectly possible to have the existence of multiple root classes.(其他语言有多个根类)

55、Java's single root class is namedjava.lang.Object, which is the parent ultimate(最终的) class of any other. For this reason, any piece of code in Java, which comes from any object, has the basic methods added byjava.lang.Object

56Cocoa can have multiple root classes. BesidesNSObject, there isNSProxyand a few others root classes; and such root classes are, in part, the reason for the existence of theNSObjectprotocol. The NSObjectprotocol determines a specifc set of(一套具体的) basic methods, expecting their implementation by the others root classes(期盼这些方法在其他地方实现), consequently(因此), making those methods available whenever and wherever they are needed. 

57TheNSObjectclass is in accordance to(根据) theNSObjectprotocol, which results in the implementation of this basic method

58Methods such as hash, description,isEqual,isKindOfClass,isProxy, and others are found in theNSObjectprotocol. NSProxytoNSObject protocol denotes that(表示) implementing the basicNSObjectmethods, it's still possible to count onNSProxyinstances. 

59SubclassingNSObjectwould pull in a lot of baggage(行李) that may cause a problem.NSProxyassists(帮助) in order to prevent this by giving you a simpler superclass that doesn't have so much extra stuff(东西) in it.

60The fact that theNSObjectprotocol is useful for root classes isn't all that interesting for most Objective-C programming, for the simple fact that we don't make use of other root classes frequently. However, it will be very convenient when you need to make your own protocols. 

61In general, you can't ask it to do any of the stuff that a normal object can do. There are times when this doesn't have any importance(一点都不重要), but in some circumstances(在一些情形), you will wish to be able to perform this task. 

62As mentioned earlier,NSObject, the root class of most Objective-C class hierarchies and throughNSObjects, your Objective-C classes can inherit an interface to the system and also gain the ability to behave as Objective-C objects. So,NSObjectis important if you want your objects to gain access to(接近) methods such asisEqual, so on, and so forth. This is where theNSObjectprotocol comes into the picture. Protocols can inherit from other protocols, which means thatMyProtocolcan inherit from the NSObject protocol: 

 @protocol MyOwnProtocol <NSObject>

       - (void)myFunction;

       @end

63This says that not only do objects that conform toMyOwnProtocolrespond to myFunction, but they also respond to all those common messages in theNSObjectprotocol. Knowing that any object in your application directly or indirectly inherits from theNSObjectclass, that it's in accordance to(根据) theNSObjectprotocol, there is no imposition(没有实施) to any additional requirements on people implementingMyOwnProtocol, while giving you the permission to use these basic methods on instances. 

64The fact that there are two different NSObjects is abnormal for the frameworks; however, it starts to make sense when you go deeper into it. TheNSObjectprotocol grants the permission to all root classes that have the same basic methods, making, also, a very easy way to declare a protocol that also includes basic functionality expected from any object. TheNSObject class introduces it all together, since it's
in accordance to the
NSObject protocol. One thing to note here is
that a custom class that's created and does not inherit
NSObjectcan be considered as a root class, but once you make your custom class inherit fromNSObject, then the root class won't be your custom class anymore, and the root class will beNSObject. However, generally, most of your custom classes should inherit from NSObjects; it will implement NSObject's functionality such asalloc, init,release, and so on and without inheriting from NSObject, these functionalities need to be written and implemented by you. 


ARC (第二章)

1In this chapter, you learned what memory management in Objective-C is and how
it works. You also learned the best practices while working with Manual Retain Release, and got an introduction to Automatic Reference Counting, Objective-C Objects, and root classes. ARC basically can be considered as a compile time guard against(
防范) memory leaks as the compiler will automatically write the release statements for you at compile time(arc 基本上被考虑在编译时间防范内存泄漏,因为编译器将自动的写释放声明 ). So, there is no need to write verbose(冗长的啰嗦的) release statements in your code to keep it clean and terse(简洁的).



2Good ideas live a long life and bad ones die fast(好主意获得久,但是坏主意死的快). In Objective-C, reference counting's long life was seen as a very good idea. The next step of evolution in this is that it became automatic, so we call itAutomatic Reference Counting(ARC), which was introduced by Apple Inc. in 2011 for application development on its desktop and mobile OS, Mac OS X Lion, and iOS 5. It changed the name of the initial referencing counting toManual Reference Counting.

3Garbage collection is only available for Mac OS X, starting with version 10.5. Also, note that iOS applications can't use Garbage collection; since it relies on(依赖) the power of the device, it will take some time to process(处理), forcing the user to wait the process end, thus producing a bad user experience(一个差的用户体验). It is also deprecated since OS X Version 10.8 is in favor of ARC and is scheduled to be removed in the forthcoming versions of OS X也被移除

4ARC is a new and innovative(革命性的) way that contains many of the Garbage collection's advantages, yet different from Garbage collection. ARC does not have any process in the background to make the object's deallocation, which gives ARC a big advantage against Garbage collection when comparing their performance 

5 ARC does not impose(利用) a runtime memory model(运行时模型) as Garbage collection does. Code compiled under ARC uses the same memory model as plain C or non- ARC Objective-C code, and can be linked to the same libraries. 

ARC only makes automatic memory management possible for Objective-C objects, inherited fromNSObject(note that(注意) in Objective-C, blocks also happen to be objects under the covers though(block 在后台也是对象)).
Memory allocated in any other way is not touched and must still be managed manually. The same goes for other resources such as file handles and sockets, such as streams. 

以其他方式生成的内存不被触及,必须被手动管理,比如文件处理,或者比如流。

6、At its core(核心处), ARC is not a runtime service; it doesn't work on program execution(ARC不是一个运行时服务,它不在项目执行时工作,不像垃圾收集装置做的一样), as Garbage collection does. On the other hand, the new Clang, the compiler frontend(前端) for C, C++, Objective-C, and Objective-C++, provides it as a two-part phase(两个阶段) (we will call these phases "cycles"). In the following diagram(), you can see these two phases. At the cycle namedfrontendas shown in the following diagram, Clang will analyze every preprocessed file for properties and objects. And then, relying on a few fixed rules, it will insert the correct statements—retain,release, and autorelease

 

7For instance, if an object is allocated and locally(在本地) corresponds to a method, this object will have areleasestatement close to that method's endpoint(在那个方法的末端). Thisreleasestatement, if it is a class property, comes into(进入) thedeallocmethod in a class, which can be your custom class or any Objective-C class. If it's a collection object or a return value, it will get anautoreleasestatement. However, if it was referenced as weak, it will be left in peace.(如果是一个弱的类型,这个对象不会被处理,待在那里)

8、The frontend also insertsretainstatements for disowned objects(非拥有对象) locally(本地的). It goes to every declared accessor(访问器) and updates them with the directive(指令)@property. It includes calls to thedeallocroutine of their superclasses such asNSObjector UIViewControlleror even your owncustomer superclass(自己定制的超类). It will also report any explicit(显式的) management call and double ownership. 

In the optimize cycle, the modified(修改的) sources are sent to load balancing by Clang.
So, it calculates the retain and release calls created for each object, and reduces all to the optimal(
最优的) minimum. This action avoids excessive(过度的)retainand releasemessages with the possibility to impact(影响) with full performance(避免影响性能)

9、属性前面的strong ,weak等字节是属性的释放规则,CLang会根据属性声明的特征,来进行自动释放

10、Sending a release statement to themyOwnStringproperty (line 24) is the responsibility of one of them. The other sends aretainmessage to the myStringargument (line 25). Before returning the last one as its result, thegetMyBarfunction sends locally aautoreleasestatement to theyBarlocal. Lastly, MRC supersedes(替代) thedeallocmethod of that class. MRC also releases themyOwnStringproperty (line 44) and invokes thedeallocmethod of its superclass (line 45); still in that method, if there is already adeallocmethod, MRC properly updates its code. 

11A very significant improvement in Objective C 2.0 is its memory model. The countless(无数的) remnants(残余) of problems from the first Objective-C implementations as a preprocessor(处理器) that induced(感应) C were cleaned up. In older versions, Objective-C objects were simply C structures, containing a pointer to their classes in their first fields, and its pointers were just able to receive messages when you wanted to send them. 

一个在2.0非常有意义的改进是内存模型

12、Now every object pointer comes into one of the following categories:weak,strong,autoreleasing, andunsafe unretained. When ARC is disabled, the programmer is responsible to take care of them all, being sure that they are all safe, for the reason that all those pointers just fit the last category.

现在每一个对象指针进化为下面策略(weak 、strong 、autoreleasing以及unsafe unretained)之一,当ARC使用之前,程序员负责照顾所有.....

13、The default category (type qualifier) is astrongpointer; they are largely correspondent to the consequences of writing flawless(完美的) defensive(防御用的) retain/release code. Assigning to astrong pointer is relative to retain the new value and release the old value, because owning references are stored in those pointers. 

默认的类型是一个强指针

14、You need to use autoreleasing pointers in order to store values that are autoreleased. In Objective-C, such pointers are the most habitual form of non- owning reference pointers; they are variables on the heap storing autoreleased values. An owning reference pointer, also known as an instance variable, will only be autoreleased when it is stored to a non-owning reference pointer, known as an autoreleasing variable. If you simply store an autoreleased reference pointer, you will have a simple attribution. 

15In order to decrease the quantity of release and retain statements in a crucial(重要的) piece
of code, it's possible to make use of
_autoreleasing, one of the four ARC type qualifiers(限定符). However, since the objects will be included in the autoreleasing pool and ARC can commonly eliminate(消除) this, it's usually not required to use this type qualifier, besides the fact that is can make things slower. 

16Weak is the last category (type qualifier) of pointer. If you used the garbage-collector mode(模式) in Objective-C, you probably already met weak pointers by storing an object in such a pointer. It's not seen as an owning reference pointer (for instance, a variable), and when the object is deallocated, this point is immediately set to nil. 

17We can count many differences between GC and ARC mode, but the very important one is about ARC being deterministic(确定性的). It's possible to see it through weak pointers. See the following code for an example: 

       id strong = [NSObject new];

       __weak id weak = strong;

       strong = nil;

       NSLog(@"%@", weak);

18Even using ARC, we are still free to useautoreleasemessages to drain/create our pool at any time. It doesn't affect the compiler when implementingretainand releasemessages, but provides hints(暗示) when it's safe to make autoreleased objects go out of scope. 

即使使用ARC,我们也可以使用autorelease ,但是在作用域之外使用autoreleased

19Note that I really meant "without worrying so much", not "without worrying at all" because even with these handy(便捷的) frameworks that create and clear the object for you, there will be cases when you want to take more control and create additional autorelease pools yourself.还是有情况,要你采用更多的控制和创建额外的自动释放池。

20TheNSAutoreleasePoolclass is used to support Cocoa's reference-counted memory management system. 

自动释放池支持引用计数框架系统。

21If a program references theNSAutoreleasePoolclass while in ARC mode, it's considered invalid and is rejected in the build phase. Instead, in ARC mode, you need to replace it with@autoreleasepoolblocks, thus defining a region where an autorelease pool is valid, as you can see in the following code:(必须用@autoreleasepool,否则就会被认为是无效的,在build阶段会被拒绝,

22、Even if you don't use ARC, you can take advantage of@autoreleasepoolblocks 

that are far more effective than the NSAutoreleasePoolclass.(@autoreleasepool 比pool class 更高效)

22、This NSAutoreleasePoolclass is like a collection of these objects and goes one by one(一个接一个) sending a release message when it's drained(倒掉)

23By using an autorelease as an alternative to a release message, you extend the object's lifetime, this time maybe even longer if the object is later retained or at least until the NSAutoreleasePool class is drained. If you put an object into the same pool more than once, for each time, it will receive areleasemessage. (通过自动释放池,延长了对象的寿命,时间可能更长,这个对象以后可能还会重新被retain或者至少直到NSAutoreleasePool被倾泻,如果一个对象被放进池子超过一次,那他就会收到多条释放消息)

24While into an environment with reference counting, Cocoa presumes(假定) there will always be an autorelease pool available; otherwise, objects that have received an autorelease message won't get released. This practice will leak memory and generate(产生) proper warning messages. (如果没有自动释放池,这么做将会产生内存泄漏,产生合适的警告信息)

25At the beginning of a cycle of the event loop, an autorelease pool is created by the Application Kit (one of the Cocoa frameworks, also known as AppKit). It(指AppKit) provides code to create and interact with(交互) GUI, and it's drained at the end of this cycle, then every autoreleased objectcreated when processing an event is just released(然后就是在程序处理中创建的每个自动释放的对象被释放). It means you don't need to create the pools yourself as the Application Kit does it for you. However, if there are many autoreleased objects created by your application, you should consider the creation of "local" autorelease pools; this is an advantage to avoid the peak memory footprint(然而,你的应用创建了很多自动释放的对象,你应该考虑很多本地自动的创建,以避免内存泄漏)

26、To create an NSAutoreleasePoolobject, you can use the regularallocand initmethods and usedrain to dismiss it. A pool cannot be retained(不能被持有); the consequences ofdrainis like a deallocation, and it's very important to do so in the same context you created it. 

27Every thread has its own stack of autorelease pools. These stacks containNSAutoreleasePoolobjects, which in turn contain autoreleased objects. Every new autoreleased object is placed on the top of the pool and every new pool is placed on the top of the stack.(每个新的自动释放对象被放到池子的顶部,每个新的池子被放到stack的顶部) A pool is removed from a stack when it's drained. Before a thread is finished, it drains every autorelease pool on its stack (一个线程被完成前,它释放在stack顶部的每一个池子)

28Despite the fact that an autorelease pool can be manually created and objects can be manually added to it, ARC still drains the pool automatically: you're not allowed to do it yourself. (不被允许,这是为什么,这里说明的是NSAutoreleasePool初始化,以及添加要释放的对象机器已经被去掉了,转而变成@autoreleasepool方式

29、To ensure that you don't have to worry about ownership, this is what ARC does: easily create autorelease pools, and make them temporarily handle the holding and releasing of autoreleased objects for you. 

确保你不担心这个拥有关系,ARC做的事:很容易的创建池子,使得这些池子临时地处理自动释放对象的持有和释放。

30、Objects that were created inside the block receive a release message when the block is terminated. An object receives release messages as many times as it receives an autorelease message inside the block. 

31If an autorelease message is not sent inside the autorelease pool block, Cocoa will return error messages and your application will leak memory. You generally don't need to create your own autorelease pool blocks, but there are three situations where you will be required to: (你通常不需要创建你自己的自动释放池代码块,但是下面的三种情形你需要强制做的)

While creating a program that is not based on UI, such as a command-line one你的项目不是基于ui,而是基于命令行

While creating a loop that generates a large number of temporary objects当创建一个循环的时候,你创建了很多的临时对象

When a secondary thread has to be created 当另外一个线程不得不被创建的时候

32Memory footprint is basically the primary amount of memory used by a program in runtime. Temporary autoreleased objects are created in countless applications, and they add to the

application's memory footprint until the block is ended. Allowing this accumulation(消耗) until the current event loop nally ends, in some cases, may result in an exorbitant overhead(过分的开销)

and you might want to quickly get rid of those temporary objects; after all, they are highly adding to the memory footprint. In this case, the creation of your own "local" autorelease pool blocks is

solution. In the end, all objects are released, consequently deallocated, beneficially reducing the memory footprint. 

33 NSArray *myUrls = <# Sample Array of URLs #>;

   for (NSURL *url in myUrls) {

     @autoreleasepool {
   /* Two objects are created inside this pool:

   NSString "contents", NSError "error"

   At the end of the pool, they are released. *

    NSError *error;         

    NSString *contents = [NSString    

    stringWithContentsOfURL:url

           encoding:NSUTF8StringEncoding error:&error];
            /* Here you can process the NSString contents,

       thus creating and autoreleasing more objects. */

       }

34As it was said before, the Cocoa framework provides factory methods(工厂方法) with autorelease for many of the basic classes such as NSString, NSArray,NSDictionary,NSColor, andNSDate 

35、我们对app的任何操作到操作的结束都可以认为是一个事件。

 

36While usingNSRunLoop, at the beginning of every run loop, an autorelease pool
will be created, and it will only be destroyed at the end of this run loop. To clarify, every temporary object created inside it will be deallocated at the end of the running iteration(
迭代). It might not be beneficial(有益的) if you are creating a large number of temporary objects inside the block; in this case, you should consider creating a new autorelease pool, as shown here 

37Notice that in order to end the autorelease pool, instead of sending areleasemessage, we sent a drain message. It was done this way because in garbage collector mode, Objective-C runtime will simply ignorereleasemessages, while the drain message won't be ignored, providing a hint(暗示) to the collector; however, it doesn't destroy the autorelease pool.(注意这里不是release而是drain,它不毁坏自动释放池

38、Application Kit creates an autorelease pool in the main thread at the beginning of each iteration, event, and releases it at the end of each iteration, thus exempting(免除) all autorelease objects created during the processing of the event. (在迭代的末尾才释放,免得在事件处理的程序中创建的很多对象被释放)

39、Basically, the run loop in iOS waits for the complete execution of an event until the application does something else. These events can be touchscreen interactions(触屏交互), incoming calls(电话), and so on.

40For each iOS event handling, a new autorelease pool is created at the beginning and released (drained) when the event's processing is completed. Theoretically(理论上讲), it can be any number of nested autorelease pools(任何数量的释放池), but remember they are created at the beginning of the event's processing(但是记住这些是在事件处理的开头)

41、NSException 异常

Exceptions may happen, and if they do occur, autorelease pools are automatically cleaned up after them. Autorelease pools prove to be a handful(一些) tool in order to write exception-safe code. 

42Despite the fact that ARC does a good job handling the memory management for us, there is still a situation when you need to use autorelease. Sometimes, we create a large number of temporary objects and many of them are only used once. In this case, you might want to free up the memory used by them.(有时,我们创建了大量的临时地对象,他们中的许多只被使用一次,这种情况下,你也许需要用autorealease来释放它)

43、 /*

     -------------------------------------------------------

     Non-ARC Environment with Memory Leaks

   */

   @autoreleasepool

   {

     // No autorelease call here

      MyObject *obj = [[MyObject alloc] init];

      /* Since MyObject is never released its

        a leak even when the pool exits

*/ } 

44 /*

     -------------------------------------------------------

     Non-ARC Environment with NO Memory Leaks

   */

   @autoreleasepool

   {

     // Memory is freed once the block ends

     MyObject *obj = [[[MyObject alloc] init] autorelease];

   }

45 /*

     -------------------------------------------------------

     ARC Environment

*/

@autoreleasepool

{ 

 MyObject *obj = [[MyObject alloc] init];

/*

   No need to do anything once the obj variable

   is out of scope. There are no strong pointers

   so the memory will be free


*/ } 

46 ARC Environment

   */

   MyObject *obj; // Strong pointer from elsewhere in scope

   @autoreleasepool

   {

       obj = [[MyObject alloc] init];

       // Not freed still has a strong pointer

   }

47You will need to create your own autorelease pool if you are making Cocoa calls outside the main thread of the Application Kit. It may happen that you create a foundation-only application for example, or separate a thread. 

如果你在App Kit外调用了Cocoa Calls,你也许需要创建你自己的单独的释放池,它也许发生在你创建了一个纯FOUNDATION应用,或者单独起了一个线程。

48、If your application generates a large number of autoreleased objects, instead
of maintaining a single autorelease pool, you are highly advised to drain the autorelease pool and create a new one frequently(
频繁地). This behavior is used by Application Kit on the main thread(这个行为尤其在主线程使用Application Kit的时候). If you neglect(忽视) this, your autoreleased objects don't deallocate, growing the memory footprint. On the other hand, if your thread doesn't make Cocoa calls, you can easily ignore this advice.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值