Reproduced iOS development----strong and weak (IOS5 new features)

Source: Internet
Author: User

IOS5 added new knowledge, that is, arc, in fact, I do not really like it, because I used to manage the memory. But learning is still necessary.

In the development process of iOS, the definition of attributes is often related to retain, assign, copy, I think we are very familiar with this, I do not introduce, there are many related articles on the Internet.

Now let's look at the New keyword in iOS5 strong, weak, unsafe_unretained. can be corresponding to the previous keyword learning strong and retain similar, weak and unsafe_unretained function almost (a bit different, and so on, these two new keywords and assign similar). With these new keywords in iOS5, you can use them without having to manage your memory manually, and programmers who turn from other languages like Java are very useful.

Strong keyword and retain, using it, reference counting automatic +1, with an example to explain everything

    1. @property (nonatomic, strong) NSString *string1;
    2. @property (nonatomic, strong) NSString *string2;

There are two of these properties,

    1. @synthesize string1;
    2. @synthesize string2;

Guess what results The following code will output?

    1. Self.string1 = @ "String 1";
    2. Self.string2 = self.string1;
    3. Self.string1 = nil;
    4. NSLog (@ "String 2 =%@", self.string2);

The result is: string 2 = string 1

Since string2 is a strong-defined property, the reference count of +1 makes them point to the value @ "String 1", which is not difficult to understand if you are familiar with retain.

Then we look at the Weak keyword:

If this declares two properties:

    1. @property (nonatomic, strong) NSString *string1;
    2. @property (nonatomic, weak) NSString *string2;


and define

    1. @synthesize string1;
    2. @synthesize string2;


Let's guess, what is the output below?

    1. Self.string1 = [[NSString alloc] initwithutf8string: "String 1"];
    2. Self.string2 = self.string1;
    3. Self.string1 = nil;
    4. NSLog (@ "String 2 =%@", self.string2);


The result is: String 2 = null

Analysis, because Self.string1 and Self.string2 point to the same address, and string2 no retain memory address, and Self.string1=nil freed memory, so string1 is nil. A pointer that is declared as weak, the pointer to the address once released, these pointers will be assigned to nil. Such a benefit can effectively prevent the wild hands. Why does Daniel say that when the pointer space is released, the pointer will be NULL when it is developed in C + +. Here we do this step with the weak keyword.

Then we'll see unsafe_unretained.

From the name can be seen, unretained and unsafe, because it is unretained so and weak a bit similar, but it is unsafe, what is unsafe, see the example below.

If this declares two properties:

and define

    1. @property (nonatomic, strong) NSString *string1;
    2. @property (nonatomic, unsafe_unretained) NSString *string2;


Guess what happens with the code below?

    1. Self.string1 = [[NSString alloc] initwithutf8string: "String 1"];
    2. Self.string2 = self.string1;
    3. Self.string1 = nil;
    4. NSLog (@ "String 2 =%@", self.string2);


Please note that I am not asking you to guess what the output will be because there will be no output at all, and your program will crash out.

The reason is, in fact, the wild pointer caused, so the wild pointer is terrible. Why do they create wild pointers? As with the pointer declared with unsafe_unretained, the Self.string1=nil has freed the memory, but string2 does not know that it has been released, so it is a wild pointer.  Then accessing the memory of the wild pointer causes crash. So try to use less unsafe_unretained keywords.

Strong,weak, unsafe_unretained are often used to declare attributes, and if you want to declare a temporary variable you have to use __strong, __weak, __unsafe_unretained, __autoreleasing, The usage is similar to that described above.

Let's take a look at examples.

    1. __strong nsstring *yourstring = [[NSString alloc] initwithutf8string: "Your string"];
    2. __weak nsstring *mystring = yourstring;
    3. yourstring = nil;
    4. __unsafe_unretained nsstring *theirstring = myString;
    5. Now all the pointers are nil

Look at one more:

    1. __strong nsstring *yourstring = [[NSString alloc] initwithutf8string: "String 1"];
    2. __weak nsstring *mystring = yourstring;
    3. __unsafe_unretained nsstring *theirstring = myString;
    4. yourstring = nil;
    5. Now the yourstring and mystring pointers are nil, and theirstring is not nil, but it is a wild pointer.

Here is also a string-related, if nsstring *str = @ "str test", which declares a string constant, so that the declaration is not limited by the above mentioned.

Such as:

    1. __strong nsstring *yourstring = @ "Test string";
    2. __weak nsstring *mystring = yourstring;
    3. yourstring = nil;
    4. Now, MyString still has a value.

NSString *str = [[NSString alloc] initwithstring:@ "test"]; This returns a string constant with the effect of nsstring *str = @ "Test"; But to follow Apple memory management, in the case of non-arc or to call release, in fact, do not need to call or memory leaks.

Introduction to the usage of __autoreleasing:

One of the C/C++,OBJECTIVE-C memory management is: Who assigns who to release. __autoreleasing can make the pair like a delay release. For example, if you want to pass an uninitialized reference to a method, which in this method actually starts the pair, then this will be the time for the __autoreleasing performance. Look at an example:

  1. -(void) generateerrorinvariable: (__autoreleasing nserror * *) paramerror{
  2. Nsarray *objects = [[Nsarray alloc] initwithobjects:@ "A simple Error", nil];
  3. Nsarray *keys = [[Nsarray alloc] initwithobjects:nslocalizeddescriptionkey, nil];
  4. Nsdictionary *errordictionary = [[Nsdictionary alloc] initwithobjects:objects Forkeys:keys];
  5. *paramerror = [[Nserror alloc] initwithdomain:@ "MyApp" Code:1 userinfo:errordictionary];
  6. }
  7. -(void) test
  8. {
  9. Nserror *error = nil;
  10. [Self generateerrorinvariable:&error];
  11. NSLog (@ "error =%@", error);
  12. }

After being translated by the compiler, it becomes:

    1. -(void) test
    2. {
    3. Nserror *error = nil;
    4. Nserror * __autoreleasing tmp = error;
    5. [Self generateerrorinvariable:&tmp];
    6. Error = TMP;
    7. NSLog (@ "error =%@", error);
    8. }

This allows you to apply the space inside the function, even if it is outside the function, and also for who assigns the principle of who is released.

The same is true for the following code, except in cases where arc is not turned on:

    1. -(NSString *) stringtest
    2. {
    3. NSString *retstr = [nsstring stringwithstring:@ "test"];
    4. return [[Retstr retain] autorelease];
    5. }


After opening the arc, it should be changed to: After testing this method is feasible, but do not have the intention to write code, __autoreleasing official website example is used in the reference parameter (like the above nserror). So it's best not to use it as follows

    1. -(NSString *) stringtest
    2. {
    3. __autoreleasing nsstring *retstr = [NSString alloc] initwithstring:@ "test"];
    4. return retstr;
    5. }

    1. -(NSString *) stringtest __attribute__ ((ns_returns_autoreleased)) {NSString *retstr = [NSString alloc] initWithString:@ "Test"];return retstr;}

Similar to the above functions. Returns a autorelease.


About Methord family, if the method name starts with Alloc, init, copy, and mutablecopy,new characters, then their return value will be retain, and the other default is Autorelease return. Here's an example of the return value:

    1. -(ID) Foo __attribute ((ns_returns_retained)); Return value retain +1, init,new,alloc,copy,mutablecopy default is this
    2. -(ID) Foo __attribute ((ns_returns_not_retained)); Returns a weak reference to the pointer,
    3. -(ID) Foo __attribute ((ns_returns_autoreleased)); Return autorlease, except default, is this
Init method has a rule, be sure to return the ID or the parent class, the child class pointer, or to have warning.
Here is the exact words:
init Methods must is instance methods and must return an objective-c pointer type. Additionally, a program was ill-formed if it declares or contains a call to an init method whose return type is NE Ither ID nor a pointer to a super-class or sub-class of the declaring class (if the method is declared on a clas s) or the static receiver type of the call (if it is declared on a protocol).
Of course you can also break this rule if you declare the method:
    1. -(void) Initstr __attribute__ ((objc_method_family (none)));
So that's right.


Original address: http://blog.sina.com.cn/s/blog_71715bf801015ntx.html
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.