Why does the "iOS Dev-117" block use copy? Extending member variables for classification by using the Objc_ method of runtime run time

Source: Internet
Author: User

(1) block

-(void) viewdidload {    [super viewdidload];    __block int a=10;    NSLog (@ "a=%d", a);    void (^blockname) () =^{        a=20;    };    NSLog (@ "a=%d", a);    Blockname ();    NSLog (@ "a=%d", a);}

--The above output is 10,10,20.

-As long as you add __block to the variable, you can modify the value of the variable in the block. Of course there are other methods such as adding static and so on.

How to do this, you need to look at the underlying code, which is the run-time code written in the C language. in the terminal utilization CLANG-REWRITE-OBJC. M file name, convert the files to . cpp of the C + + The underlying code, which can be used to analyze the underlying implementation principle, can be Open. cpp file name, open view.

The core principle is that, because there is a __forwarding parameter, each output is called the value of A.__forwarding->a. and block is essentially a pointer to the structure of the address.


(2) runtime, usually we write code in fact will eventually turn into runtime code, efficient. But we usually write with OC. If you do not want to write using run-time code, you can add the following class.

#import <objc/message.h>//need to use to send a message, when the function is set #import <objc/runtime.h>//there are some special functions

We usually use the method, in fact, is the message mechanism, used to be objc_msgsend this function. We just have to include the header file above.<objc/message.h>, you can also use this function to write code.

-One use value. Our usual classification can only extend the method of a class, but not its member properties. Some of the methods used (as follows) can dynamically expand member properties for a class.

static double heightkey;-(void) SetHeight: (double) height{    objc_setassociatedobject (self, &heightkey, @ ( Height), objc_association_assign);} -(double) height{    return [Objc_getassociatedobject (self, &heightkey) doublevalue];}

--Iterate over the member variables of the class (the user is able to iterate through all of the variable uniform operations, such as encode or decode)

#import "ViewController.h" #import "Person.h" #import <objc/message.h> #import <objc/runtime.h> @interface Viewcontroller () @end @implementation viewcontroller-(void) viewdidload {    [super viewdidload];        unsigned int count=0;    All member properties of the class can be obtained, by default pointing to 0, that is, the first member property of a class    Ivar *ivars=class_copyivarlist ([Person class], &count);    Traverse member variable for    (int i=0; i<count; i++) {        Ivar ivar=ivars[i];        const Char *name=ivar_getname (Ivar);        const Char *type=ivar_gettypeencoding (Ivar);        NSLog (@ "%s,%s", Name,type);    }}

The output is:

_age,i_name,@ "NSString"

(3) Why is the block variable defined with copy? Where is the block placed?

--By default, the block is archived in the stack and may be recycled at any time, requiring a copy operation. This is the copy we used when we defined the block. Rather than weak and so on.

By default it is placed on the stack and may be destroyed at any time by    Void (^blockname) () =^{            };    Once a copy operation is made, it can be placed in the heap.    //[blockname copy];    The following methods are also the same. However, it can only be used in non-arc.    //block_copy (blockname);        The reason for using retain is useless: retain just increments the count, block memory is still in the stack, and it is not transferred to the heap.

--block if it is copy, it will never be released if it uses the object of the class it is in. That is, the person object is a strong pointer in the heap, and the person is in Blockname, and the code that Blockname points to is also in the heap, that is, the code of its person.age=20 is also in the heap, and there is a person object in the code. So this in turn points to the person object. So in the direction of each other, can never be released.

    Person *person=[[person Alloc]init];    person.blockname=^{        person.age=20;    };

The workaround is as follows. It is not possible to place __unsafe_unretained directly on the line where the person object was created. Because if that's the case, the person object is a weak pointer, and is born dead. The purpose of introducing weak pointer Person0 is to use a weak reference when the person0 of the Block code refers to the object, so that no 2 strong references are pointed to each other. You can also use __weak.

    Person *person=[[person Alloc]init];    __unsafe_unretained person *person0=person;    person.blockname=^{        person0.age=20;    };



Why does the "iOS Dev-117" block use copy? Extending member variables for classification by using the Objc_ method of runtime run time

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.