How to get started with and use ARC for iOS/Mac Development)

Source: Internet
Author: User
Tags switch case

Teach you how to get started with ARC-iOS/Mac development and use Revolution of Objective-c. some examples in this article are taken from the tutorials and public content about ARC in iOS 5 Toturail, it is only used for technical exchanges and discussions. Please do not use part or all of the content in this article for commercial use. Thank you for your cooperation. You are welcome to repost this article, but please indicate the source of this article: This article is suitable for the audience: there is a certain foundation for iOS development, familiar with the Reference Counting mechanism for memory management in iOS development, children's shoes that have heard of the ARC mechanism but have never been used for various reasons. This article will start with the ARC mechanism to analyze the great mechanism for emancipating the masses of iOS developers, and gradually guide you to use the ARC. Once you get used to ARC, you will be conquered by its simplicity and efficiency. Although it has been almost a year before WWDC2011 and iOS 5, many developers have not used new methods to improve their own level, which is very obvious in the use of ARC (especially in China, almost seldom seen in the same industry turning to ARC ). I have asked some colleagues why they didn't turn to ARC. Many people say they are worried that memory management is not controlled by themselves .. in fact, I personally think this is a fear of new things due to lack of understanding about the ARC mechanism and self-confidence. As the most "catch up with fashion" profession, this mentality will be quite unfavorable. In this article, we hope to clearly express the mechanism and usage of ARC, and to be a supplement to the lack of Chinese introductory teaching. What is ARCAutomatic Reference Counting, automatic Reference Counting, that is, ARC, can be said to be the biggest change and the most exciting change introduced by WWDC2011 and iOS5. ARC is a feature of the new LLVM 3.0 compiler. Using ARC can be said to solve the trouble of manual memory management hated by iOS developers. It is very easy to use ARC in projects: you only need to write code as usual, but never write the retain, release and autorelease keywords ~ This is the basic principle of ARC. When ARC is enabled, the compiler will automatically insert retain, release, and autorelease where the code is appropriate. As a developer, there is no need to worry that the compiler will do wrong (unless the developer mistakenly uses ARC ). Okay, ARC is quite simple ~ This tutorial ends. Wait... There may be other problems. The most serious problem is, "How can I determine that there will be no problems for the ARC to manage ?" Or "using ARC will degrade program performance ". The question that ARC cannot be dealing with memory management has existed since its birth, and more code is turning to ARC and achieving good results, this proves that ARC is an effective mechanism to simplify development complexity. By studying the principle of ARC, we can know that using ARC can even improve program efficiency. Next we will explain in detail the running mechanism of ARC and provide a step-by-step tutorial to convert non-ARC programs to ARC. The working principle of ARC manual memory management should be very clear to everyone. Simply put, you can avoid most of the trouble in manual memory management by following the following three points: If you need to hold an object, if this object is no longer used after a retain is sent to it, you need to send a release (or autorealse) to it every time you call retain, alloc, or new, A corresponding release or autorealse call is required. Beginners may only know these rules, but they will inevitably make mistakes in actual use. However, when developers often use Manual reference to count Manual Referecen Counting (MRC), these rules will gradually become instinct. You will find that there is one less release code, so as to reduce or eliminate memory management errors. It can be said that the MRC rules are very simple, but they are also very error-prone. Very small errors may cause crash, OOM, and other serious problems. In the MRC era, to avoid accidental forgetting to write release, Xcode provides A very useful tool to help with possible code problems (Shift +? Can indicate potential memory leakage or excessive release. While ARC goes further on this basis: ARC is a feature of the Objective-C compiler, rather than runtime features or garbage collection mechanisms, what ARC does is to automatically insert release or autorelease into the appropriate position during code compilation, just as you did in MRC. Therefore, at least in terms of efficiency, the ARC mechanism will not be weaker than MRC, because the maintenance of reference count and partial optimization can be completed in the most appropriate place, using ARC can even achieve higher operational efficiency than MRC. Learning about the ARC mechanism is very simple. In the MRC era, you need to retain an object you want to keep, but now you don't need it. The only thing we need to do now is to use a pointer to point to this object. As long as the pointer is not left blank, the object will remain on the heap. When the pointer points to a new value, the original object will be release once. This applies to instance variables, synthesize variables, or local variables. For example, 1 NSString * firstName = self. textField. text; firstName now points to the NSString object, and this object (the content string of textField) will be held. For example, the string @ "OneV" is used as an example (although strings should not be used as an example, because the retainCount rules of strings are actually different from common objects, let's look at it as a common object ...), At this time, firstName holds @ "OneV ". A strong pointer, of course, can have more than one owner of an object (similar to retainCount> 1 in MRC ). In this example, self. textField. text is also @ "OneV", so now there are two pointers pointing to the object @ "OneV" (held twice, retainCount = 2, in fact, there is a problem with retainCount for the NSString object, however, anyway ~ That's all .). After two strong points to the same object for a while, maybe the user entered other things in textField, then self. textField. the text pointer clearly points to other strings, such as @ "onevcat", but the original object already exists because another pointer firstName holds it. The pointer pointing relationship is as follows: one strong points to another object only when firstName is set to a new value, or the space beyond the scope of the function (for example, it is a local variable but the method is executed completely or it is an instance variable but the instance is destroyed ), at this time, firstName does not hold @ "OneV". At this time, no pointer is directed to @ "OneV". In ARC, when this happens, the object @ "OneV" is destroyed and the memory is released. No strong points to @ "OneV", and memory release is similar to firstName and self. textField. A pointer such as text uses the keyword strong for flag, which means that the object will not be destroyed as long as the pointer points to an object. Conversely, a basic rule of ARC is that an object will not be destroyed as long as it is directed by any strong pointer. If the object is not directed by any strong pointer, it will be destroyed. By default, all instance variables and local variables are of the strong type. It can be said that the pointer of the strong type is similar to the retain property in the MRC era. Since there is strong, there must be weak ~ A weak type pointer can also point to an object, but does not hold this object. For example, 1 _ weak NSString * weakName = self. textField. in text, a strong pointer and a weak point to the same object. Here, a weak pointer weakName is declared, which does not hold @ "onevcat ". If the content of self. textField. text changes, as mentioned earlier, "as long as an object is directed by any strong pointer, it will not be destroyed. If the object is not directed by any strong pointer, it will be destroyed. At this time, the pointer pointing to @ "onevcat" does not have a strong pointer, and @ "onevcat" will be destroyed. At the same time, under the ARC mechanism, all weak pointers pointing to this object will be set to nil. This feature is quite useful. I believe that countless developers have been troubled by EXC_BAD_ACCESS caused by pointer pointing to released objects. After using ARC, pointers of the strong or weak types will be used, it no longer points to a dealloced object and solves the crash caused by accidental release from the root. Strong points to another object, memory is released, and weak is automatically set to nil. However, in most cases, weak type pointers may not be very common. A common usage is that when two objects have a inclusion relationship: Object 1 has a strong pointer pointing to object 2 and holding it, in object 2, only one weak pointer refers to object 1, thus avoiding loop holding. A common example is the common delegate Design Pattern in oc. viewController has a strong pointer pointing to the UITableView managed by it, while the dataSource and delegate pointers in UITableView both point to the weak pointer of viewController. It can be said that the weak pointer behavior is similar to the assign in the MRC era, but it is still different considering that the weak pointer is smarter (it will automatically point to nil. Let's talk about the details later. A typical delegate design pattern. Note that the code similar to the following seems meaningless: 12 _ weak NSString * str = [[NSString alloc] initWithFormat:…]; NSLog (@ "% @", str); // The output is "(null)" because str is weak, it does not hold the NSString object from alloc, therefore, this object is destroyed at the same time because there is no valid strong pointer pointing. If we write the above Code in Xcode, we should get a warning, because it seems unlikely to happen at any time. You can replace weak with strong to eliminate the warning, or do not write anything above, because the default pointer type in ARC is strong. Property can also be marked with strong or weak, simply replacing the original retain and assign with strong or weak. 12 @ property (nonatomic, strong) NSString * firstName; @ property (nonatomic, weak) id delegate; ARC can save developers a lot of code, after using ARC, you no longer need to worry about when retain and release, but this does not mean that you don't need to think about memory management. You may need to ask yourself this frequently: who holds this object? For example, the following code assumes that array is an NSMutableArray with at least one object in it: 123id obj = [array objectAtIndex: 0]; [array removeObjectAtIndex: 0]; NSLog (@ "% @", obj); In the MRC era, the lines of code should be suspended, because the 0 object in the array will be destroyed immediately after it is removed, so obj points to a dealloced object, so EXC_BAD_ACCESS will appear in NSLog. Since obj is strong in ARC, it holds the first object in array, and array is no longer the only holder of this object. Even if we remove the obj from the array, it is still held by other pointers, so it will not be destroyed. One point reminds that ARC has some disadvantages. For Beginners, it may only be used on objective-c objects (that is, objects inherited from NSObject ), however, if more underlying things are involved, such as malloc () or free () in the Core Foundation, ARC will be overwhelmed. At this time, you still need to manually manage the memory. We will see some examples in this area later. In addition, to ensure that the ARC can work correctly, some syntax rules will become slightly stricter due to the ARC. ARC can indeed add retain or release for the code in the appropriate place, but this does not mean that you can completely forget the memory management, because you must manually set the strong pointer to nil in the appropriate place, otherwise, the app may use oom. To put it simply, you must always be clear about who holds what objects and when these holders should point to nil. ARC is bound to be the trend of Objective-C and Apple development. In the future, more and more projects will adopt ARC (or even exclude the possibility that MRC will be discarded in a future version ), apple has always encouraged developers to start using ARC because it can indeed simplify code and enhance its stability. It can be said that after using ARC, the crash caused by memory problems is basically a pass-through (OOM except: P). We are on a node transformed from MRC to ARC, so sometimes we need to switch back and forth between the ARC and MRC code and adapt. Apple has also thought of this, so it provides some ARC and non-ARC Code Mixing Mechanisms for development, which will be listed in subsequent examples. In addition, ARC can even be used in C ++ code. By following some code rules, in iOS 4, you can also use ARC (although I personally think that there is basically no need to adapt to iOS 4 in the era of iOS 6). In short, smart developers always try to automate processes as much as possible and reduce their workload. ARC just offers us the following benefits: automation helped us complete a lot of work that we previously needed to do manually, so for me, turning to ARC is not worth considering. After so many specific operations, we can finally practice it. After the decision to use ARC, many developers are faced with the primary problem of not knowing how to start. This may be because some projects have already been written in MRC, and you don't want to bother with the transformation. Or because of a strange problem encountered in the use of ARC in the new project, you can discard the ARC and return it to MRC. This is a common problem. Below, we will use a demo to guide everyone to the world of ARC. The DemoDemo example is very simple. It is an application for searching singers, including a simple UITableView and a search box. When a user searches in the search box, the MusicBrainz API is called to complete name search and matching. MusicBrainz is an open music information platform that provides a free XML webpage service. If you are interested in MusicBrainz, visit its official website. The Demo Start example can be downloaded from here. In order to take care of new users, we will briefly describe it here. Open the download example in Xcode and you can see the following content (skip this section for Xcode and iOS developers): AppDelegate. h/m: This is the delegate of the entire app. There is nothing special about it. Every iOS/Mac program enters the app lifecycle after the main function. The original viewController is loaded and displayed in the Window. In addition, appDelegate is also responsible for handling the event MainViewController. h/m/xib, which is the most important ViewController in the demo, including a TableView and a search entry. SoundEffect. h/m Simple playing sound class, playing a sound effect when the MusicBrainz search is complete. Main. m program entry. All c Programs start to execute AFHTTPRequestOperation. h/m from the main function. This is part of the famous network framework AFNetworking and is used to help easily process web Service requests. Only this class is included, but not all AFNetworking is included, because we only use this class. The complete framework code can be found on github related pages as a commonly used progress bar indicator when searching to prompt users to be searching, please wait. Bundle is a resource package that contains several images used in this class. The purpose of bundle package entry is to facilitate resource management, on the other hand, in order not to conflict with other resources, the Resource Name in Xcode is the unique identifier of the resource. resources with the same name can only appear once, put it in the bundle package to avoid this potential problem ). SVProgresHUD can be found here. The content in the searchResult array is displayed in TableView. When a user searches, use AFHTTPRequestOperation to send an HTTP request. After receiving a response from MusicBrainz, the result is put into the searchResult array and displayed in tableView, if the returned result is null, it is not found in tableView. The main logic is in MainViewController. -searchBarSearchButtonClicked in m: In the method, a URL is generated for query. The request header is replaced according to the requirement of MusicBrainz, the return logic is completed, and the UI is refreshed in the main thread. The whole program is relatively simple ~ The automatic conversion from MRC to ARC is back to the topic. We are talking about ARC. Ignore the technical details about rest api and XML parsing for the moment .. the entire program uses MRC for memory management. First, let's convert this demo to ARC. Basically, converting to ARC means removing all the retain, release, and autorelease keywords. Before that, let's clarify a few things: Xcode provides an automatic ARC Conversion Tool, it can help you convert source code to ARC. Of course, you can also perform ARC conversion by yourself. You can also specify to disable ARC for some code that you do not want to convert, this is very helpful for a lot of complicated third-party libraries that haven't been transferred to the ARC, because the code is super easy if you don't write the code and you want to modify it... For our demo, we will adopt all three policies to illustrate the problem. Note that this is only to demonstrate how to convert. In practice, this is not necessary, and in the future, the vast majority of cases should be from the establishment of the project to the ARC. Choosing LLVM compiler 3.0 first, ARC is the feature of the LLVM3.0 compiler, while the default compiler for older projects, especially in the Xcode3 era, is likely to be GCC or LLVM-GCC, therefore, the first step is to check whether the compiler is correct. On the Project Settings panel, select target. In Build Settings, select Compiler for C/C ++/Objective-C as Apple LLVM compiler 3.0 or later. To ensure smooth subsequent conversions, I personally suggest you enable both Treat Warnings as Errors and Run Static Analyzer, make sure that the code is still not warned or memory problems after the compiler is changed (although static analysis may not guarantee this, it is better than nothing ). Okay ~ Clean (Shift + Cmd + K) and Bulid. There are no warnings or errors in the modified demo project. This is a good start. (This is a good time to fix warning codes. Make sure that the original code has no memory problems before conversion ). The next step to open the ARC is to complete the great conversion from MRC to the ARC. On the Build Settings page, change Objective-C Automatic Reference Counting to YES (if not, check whether the small tag in front of the search bar is set to All .. this option does not appear in Basic), so that our project will enable ARC in all source code. Then... Try to compile and check out the numerous errors. Please be patient and listen to the compiler, because it is often your only partner. This is normal, because retain, release, and so on are not allowed in ARC, the MRC code will certainly have something. We can manually fix these errors one by one, but this is very troublesome. Xcode provides us with an automatic conversion tool that can help rewrite the source code. Simply put, we can remove unnecessary statements and rewrite some property keywords. Use the conversion ARC tool provided by Xcode to select the file to be converted. This tool is Convert to Objective-c arc under Edit-> Refactor. After clicking this tool, we will choose which files to Convert, in order to illustrate the methods except automatic conversion, we only select several of them (MainViewController. m and AFHTTPRequestOperation. m is not converted, and then we manually convert the two to ARC ). Note that there is a warning sign on this dialog box that tells us that the target is already ARC, because we have set to enable ARC in Build Settings before, in fact, after conversion, Xcode will automatically enable the ARC for us. After clicking check, Xcode tells us an unfortunate message that cannot be converted. You need to fix the ARC readiness issues .. the following also tells us that we want to see all the so-called ARC readiness issues. We can hook the Continue building after errors in the General settings... What the f ** k... Okay ~ Follow the advice of Xcode "Cmd +", and then tick the Continue building after errors before building. I am so obedient that I can still mark the problem, but I should be able to see all the problematic code on the issue panel. In our example, the problem lies in SoundEffect. m: 12345678 NSURL * fileURL = [[NSBundle mainBundle] URLForResource: filename withExtension: nil]; if (fileURL! = Nil) {SystemSoundID theSoundID; OSStatus error = Response (CFURLRef) fileURL, & theSoundID); if (error = kAudioServicesNoError) {soundID = theSoundID ;}} here the code tries to forcibly convert an NSURL pointer to a CFURLRef pointer. Here we have some Core Services, especially Core Foundation (CF). The AudioServicesCreateSystemSoundID () function accepts CFURLRef as a parameter, which is a concept of CF, but what we create at a higher abstraction level is an NSURL object. In the Cocoa framework, there are many top-level objects that abstract the underlying layer. in use, we can usually treat these two objects differently, this type of object is a "free bridge" Object (toll-free bridged ). NSURL and CFURLRef are a friendly example. Here, CFURLRef and NSURL can be replaced. Generally, to ensure that the Code is correct at the underlying level, the parameters passed in For Calling C-based APIs in iOS development are generally CF objects, in Objective-C, all API calls are passed into the NSObject object. Therefore, a conversion is required when free bridging is used to call the c api. However, when using ARC compilation, the compiler needs to know what operations are required for these bridging objects due to memory management. If an NSURL object replaces CFURLRef, who should decide the memory release and object destruction outside the target region? To solve this problem, three keywords: bridge, bridge_transfer, and _ bridge_retained are introduced. The actual code behavior determines which keyword to select for conversion. If you are interested in the free bridging mechanism, you can look for relevant content, such as the applicable type, internal mechanism, and an introduction ~ Later, I will explain this problem back to the demo. Now we add _ bridge before the code above (CFURLRef) for conversion. Then run the ARC Conversion Tool. At this time, check that there should be no other problems, so let's perform the conversion ~ Of course, there will be a preview interface before the real conversion. Here we 'd better check whether the conversion is as expected .. if there is a large-area error, no backup, or a variety of accidents, you can cry... Before and after the changes are relatively simple, the basic is to remove unnecessary code and change the property type, in fact, if you are confident, you do not need to read it every time, however, if it is the first time to execute the ARC conversion operation, I suggest you take a look at the changes, so that you can have an intuitive understanding of the ARC. Check it again. It should be okay .. note that main. in m, the changes in autoreleasepool and the deletion of [super dealloc] in all dealloc calls are also the main changes from MRC to ARC .. okay ~ After the conversion is complete, let's build again to see if... there should be some warnings. For the original retain property, it is safer to convert it to strong. In LLVM3.0, the automatic conversion is done, but in 3.1, the property is not strong by default, in this case, there is a warning when using the property assignment. We can add strong to the property declaration ~ Then SVProgressHUD. m may be faulty because the original author wrote the release code and other code in a line. as a result, only part of the code that should not exist is deleted during automatic conversion, and the call to the null variable is deleted .. the story after automatic conversion is then compiled without any errors or warnings. Great ~ Wait... We haven't processed MainViewController and AFHTTPRequestOperation just now, so there should be something like release in these two files ..? Let's take a look at these two files. There are various release files, but why can they be compiled ?! Even though there are N errors before the automatic conversion... The answer is simple. Because the two files are not checked during automatic conversion, the compiler marks "do not use ARC compilation" for the two files after automatic conversion ". You can see MainViewController under Building Phases of target. m and AFHTTPRequestOperation. m files are appended with the-fno-objc-arc compilation tag. Files Added with this tag will not be compiled using the ARC rules. (If you want to force ARC to be enabled for several files, you can add the-fobjc-arc tag to them) it is obvious that the force is not to use ARC to provide such compilation markup, because there is always a part of third-party code that is not converted to ARC (probably because the maintainer is lazy or has terminated maintenance ), so for this part of code, to quickly complete the conversion, it is best to use the-fno-objc-arc Mark to prohibit the use of ARC on these source code. For ease of searching, we will list some possible problems during conversion. Of course, when using ARC, we also need to avoid these problems in the Code: "Cast... Requires a bridged cast "is a problem we encountered in the demo. We will not repeat the author er type 'X' for instance message is a forward declaration, which is often a reference problem. ARC requires a complete forward reference, that is, in the MRC era. in h, you can declare @ class, but in ARC, if you call a method in the parent class that is not covered by a subclass, you must pair the parent class. h references. Otherwise, compilation fails. Switch case is in protected scope now the switch statement must be added with {}. ARC needs to know the scope of local variables. After {} is added, the switch syntax is stricter, otherwise, memory management may fail if there is no break branch. A name is referenced outside the NSAutoreleasePool scope that it was declared in... This is because I wrote my own autoreleasepool, And the variables stated in the original pool during the conversion will be limited in the scope of the new @ autoreleasepool. The solution is to apply for the variable declaration to the pool. ARC forbids Objective-C objects in structs or unions can be said that the strictest restriction introduced by ARC is that OC objects cannot be placed in the C struct .. therefore, the following code is unavailable: 1234 typedef struct {UIImage * selectedImage; UIImage * disabledImage;} ButtonImages; this problem can only be found .. changing the original structure or something .. manual conversion most of the demo conversions were just done, with MainViewController and AFHTTPRequestOperation being MRC. However, since-fno-objc-arc is used, compilation and running are now all correct. Next, let's take a look at how to manually convert MainViewController to ARC, which also helps to further understand the ARC rules. First, we need to change our mindset... For MainViewController. h, in. in h, two instance variables are declared: 12345 @ interface MainViewController: UIViewController {NSOperationQueue * queue; NSMutableString * currentStringValue;}. Let's take a closer look at why the instance variable statement is displayed in the interface? Generally, instance variables are used only in the instance of the class, and the users of the class you write do not have to know much about the instance variables in your class. The vast majority of instance variables should be protected or private, and the operations on them should only use setter and getter, which is exactly the work of property. It can be said that it is a bad habit to write instance variables in the header file. The better place for writing instance variable names should be more closely related to class implementation. To hide details, we should consider writing them in @ implementation. The good news is that in LLVM3.0, whether or not ARC is enabled, the compiler supports writing instance variables to the implementation file. Even if there is no special need to use property again, we should not write meaningless instance variable declaration, because when binding in @ synthesize, we can set the variable name, this can simplify the code. Here we do not need property for two instance variables (external members should not be able to access them), so we move the Declaration to. m. The modified. h is like this. It is very concise and easy to understand ~ 12345 # import @ interface MainViewController: UIViewController @ property (nonatomic, retain) IBOutlet UITableView * tableView; @ property (nonatomic, retain) IBOutlet UISearchBar * searchBar; @ end then. m starts with 12345 @ implementation MainViewController {NSOperationQueue * queue; NSMutableString * currentStringValue. m is indeed the place where these instance variables should be... Build, no problem .. of course, similar operations can be performed on the SoundEffect class, which will make people who use your class very happy, because. the simpler the h, the better .. p.S. another benefit can be reduced. references in h to reduce the Compilation Time (although not obvious =. =) Then you can enable ARC in MainViewController. The method is simple. Delete the-fno-objc-arc Mark of the related files in Build Phases ~ And then, of course, there are a lot of errors. Let's change them one by one. Although it is not fun, it will be very successful in the future ~ (If you have unfortunately succeeded in building after enabling ARC, congratulations, you have encountered the Xcode bug. Please run Cmd + Q and re-open Xcode to = _ =) dealloc is the most dense red line because each row is release. Here, dealloc does not do anything except release and super dealloc, so simply delete the entire method. Of course, dealloc will still be called when the object is destroyed. Therefore, when we need to manage non-ARC-managed memory and necessary logical operations, dealloc should be retained. Of course, this involves the CF and the following layers: for example, CFRelease () is required for the CF object of retain, and free () is required for the stuff from malloc () to the heap () for the added observer, you can remove it here, the schedule timer is here invalidate, and so on ~ [Super dealloc] This message no longer needs to be sent, and ARC will automatically handle it for you. In addition, in the MRC era, a common task is to set the delegate pointing to itself in dealloc to nil (otherwise, we will wait for EXC_BAD_ACCESS: P), but now the delegate is generally weak, so after self is destroyed, this pointer is automatically set to nil. You don't have to worry about it anymore. That's great .. removing various release and autorelease is very straightforward and there is no problem. Just remove it ~ Let's not talk about the Property in MainViewController. the class extension in m defines two property: 1234 @ interface MainViewController () @ property (nonatomic, retain) NSMutableArray * searchResults; @ property (nonatomic, retain) SoundEffect * soundEffect; @ end the declarative type is retain. Discussions about retain, assign, and copy are no longer discussed here. In the MRC era, using property can help us simplify the retain and copy of objects when using dot notation. In the ARC era, this seems redundant. In my opinion, using the property and vertex methods to call setter and getter is unnecessary. Property only needs to expose the required data to other classes in. h. In this class, you only need to use instance variables. (Update. Now I am not entangled in this point. Just feel free to understand it. However, it may be better to use the dot method. At least you can tell whether the instance variable is operated or whether setter and getter are called ). So we can move the @ property and @ synthesize of searchResults and soundEffect to the instance variable Declaration: 1234567 # import "plementation MainViewController {NSOperationQueue * queue; NSMutableString * currentStringValue; NSMutableArray * searchResults; SoundEffect * soundEffect;} accordingly, we need to set the corresponding self. searchResult and self. self. remove all. Note that although we have removed the property and synthesize of soundEffect, we still have a lazy loading method-(SoundEffect *) soundEffect, the magic is that (You may not know before) the dot method does not need the support of the @ property keyword, although it is used for most of the time .. (property is only a declaration of setter or getter, And the vertex method is a call to it. In the implementation of this example, we actually implement the-soundEffect getter method, so there is no problem with the getter call of the vertex method on the right of the equal sign ). To avoid misunderstanding, we recommend that you rewrite the getter call of self. soundEffect to [self soundEffect]. Then let's take a look at the property ~ in. h ~ There are two retain IBOutlet. The retain keyword is still available in ARC. It plays the same role as strong in ARC. To avoid confusion, it is best to write it as strong as needed, which is more in line with the ARC rules. For these two properties, we declare them as weak (in fact, except for the top-level IBOutlet, the outlet written by myself should be weak ). The user interface obtained by loading xib is a part of view hierarchy when it is loaded from the xib file, and all directions in view hierarchy are strong. Therefore, the UI object pointed to by outlet should not be held again. The most obvious advantage of writing these outlets into weak is that you no longer need to set these outlets to nil in the viewDidUnload method (otherwise, even if the view is destroyed, however, these UI objects cannot be released because they are still pointed by the outlet pointer, and the code is much simpler ..). In our demo, change the IBOutlet property to weak and delete the IBOutlet content in viewDidUnload ~ Summarize the keyword type of the newly added property: strong is similar to the original retain, and strong's property will correspond to the _ strong pointer, it holds the weak of the object to which it points and does not hold the object to which it points, and it can set itself to nil when the indicated object is destroyed, basically all outlet should use weakunsafe_unretained, which is the original assign. This keyword copy is basically the same as the original one to support iOS4 .. copy an object and create a strong pointer assign for it. For the object, you should never use assign. If you really need it, replace it with unsafe_unretained (when this is basically not found, most assigns should be replaced by weak ). However, assign is used for basic types such as int, float, and BOOL. In particular, for NSString objects, many people like to use copy in the MRC era, while in the ARC era, they generally like to use strong... (I don't know why... please advise) The details of free bridging MainViewController now the remaining problems are all about bridging conversion ~ There are three parts about bridging: (NSString *) CFURLCreateStringByAddingPercentEscapes (...): CFStringRef to NSString * (CFStringRef) text: NSString * To CFStringRef (CFStringRef) @ "! '();: @ & = + $ ,/? % # [] ": The NSString to CFStringRef compiler reports an error for the first two. The last one is constant conversion, which does not involve memory management. With regard to toll-free bridged, NSString and CFStringRef are the same thing. You can create a CFStringRef: 1 CFStringRef s1 = [[NSString alloc] initWithFormat: @ "Hello, % @! ", Name]; then, alloc is here and s1 is a CF pointer. to release it, you need to: 1 CFRelease (s1 ); similarly, CFStringRef can be used to convert an NSString object (MRC): 12345 CFStringRef s2 = CFStringCreateWithCString (kCFAllocatorDefault, bytes, kCFStringEncodingMacRoman); NSString * s3 = (NSString *) s2; // release the object when you're done [s3 release]; in ARC, the compiler needs to know who should release these pointers, if we regard an NSObject as a CF object, ARC will no longer be responsible for its release (remember that ARC is only for NSObject ). For objects that do not need to change the owner, simply use the simple bridge, such as the previous transformation in SoundEffect. m. Here, for the conversion of (CFStringRef) text, ARC has been responsible for the NSObject memory management of text, so here we need a simple bridge. For the CFURLCreateStringByAddingPercentEscapes method, create in the method implies that this method will form a new object. If NSString conversion is not required, in order to avoid memory problems, we need to use CFRelease to release it. Here we need an NSString, so we need to tell the compiler to take over its memory management work. Here we use the bridge_transfer keyword to hand over the memory management right from CF object to NSObject (or ARC ). If we only use bridge here, the memory management owner will not change, so there will be a memory leak. In addition, you may see CFBridgingRelease (), which is actually the inline Writing of transfer cast. In short, the principle to be remembered is that if the function name contains one of Create, Copy, or Retain when it involves something on the CF layer, it indicates retainCount + 1 of the returned object, for such objects, the safest way is to put them in CFBridgingRelease () to balance retain and release. There is also a bridge method, __bridge_retained. As the name suggests, this conversion will add retainCount to 1 during conversion. Similar to CFBridgingRelease (), there is also an inline method CFBridgingRetain () to balance with CFRelease. Note that not all CF objects are free-Bridging. For example, all objects in Core Graphics are not free-bridging (such as CGImage, UIImage, CGColor, and UIColor ). In addition, not only free bridge objects can be used for bridge bridging. A good special case is void (pointer to any object, similar to id). For conversion between void and any object, generally, _ bridge is used. (This is useful in using ARC in Cocos2D.) So far, the whole project has been completed by ARC ~ For third-party code that does not support ARC such as AFHTTPRequestOperation, we generally choose not to use ARC (or wait for the open-source community to update the ARC adaptation version ). It is foreseeable that more and more code will be switched to ARC in the near future, but there will certainly be a lot of code temporarily or always keep MRC and so on, so you don't have to worry too much about this code ~ I wrote so much at the end. I hope you can have a comprehensive understanding and understanding of ARC. ARC must be a future trend, which can also greatly reduce the amount of code, reduce a lot of meaningless repetitive work, and improve the stability of the app. However, everything is still written on paper, and you will try to use ARC ~ In the next project as a developer ~ I believe you will fall in love with this make life easier method just like me ~

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.