Does sending a message to an empty object in OC crash?

Source: Internet
Author: User
Tags shallow copy

First of all, the OC to nil message, the program will not collapse.

Because the function calls of OC are implemented through Objc_msgsend, the operation of NULL pointers will cause crash problems relative to C and C + +, and Objc_msgsend will judge self to decide whether to send messages. If self is nil, then selector is empty and returns directly, so there is no problem . Depending on the method return value, sending a message to nil may return nil (the return value is an object), 0 (The return value is some underlying data type) or 0x0 (the return value is an ID), and so on. But to [nsnull
Null object is crash when it sends a message, because the Nsnull class has only one null method.

Of course, if an object has been freed (the reference count is 0), then the call to the method at this time will certainly be crash, because this time the object is a wild pointer ( pointing to a Zombie object (the object's reference count is 0, the pointer to the memory is not available) . , the safe approach is to reset the object to nil and make it a null pointer, and you can verify the manual release object after closing the arc. about Nil

Nil is defined as null pointer to Object-c object, which means that an OC object pointer is null, essentially (ID) 0, the literal 0 value of the OC object

However, it is necessary to mention that the OC in the null pointer message will not crash the language characteristics, because the OC function calls are sent through the objc_msgsend message to achieve, relative to C and C + +, the operation of the null pointer will cause crash problems, and OBJC_ Msgsend will decide whether to send the message by judging self, and if self is nil, then selector will be empty and returned directly, so there is no problem.

Add here that if an object has been released, then the call to the method at this time is definitely going to be crash, because this time the object is a wild pointer, the safe way is to reset the object to nil, make it a null pointer, You can verify the manual release object after closing the arc.

NSString *name = @ "Allen";

if (name!= nil && [name isequaltostring:@ "Allen"]) {
    NSLog (@ "Name:%@", name);
} else {
    NSLog (@ "name is nil ");
}

or
if ([Name isequaltostring:@ "Allen"]) {
    NSLog (@ "Name:%@", name);
} else {
    NSLog (@ "name is nil"); c10/>}

Both of the above judgments are correct, and we don't have to worry about the crash when calling Isequaltostring when name is nil, but I still want to say that it is a good habit to judge whether it is nil before using an object, for two reasons personally: Reduce time complexity (feel like that), if you increase the nil judgment, then do not need to send a message to the null pointer, send a message is actually a time-consuming operation. The details can be seen here to judge the empty habit is actually a good thing, so when you switch the language is not easy to make mistakes. about Nil

The definition of nil is null pointer to Object-c class, which means that a class pointer is null. The essence is (class) the literal 0 value of the 0,oc class.

Class class = [NSString class];
if (class!= Nil) {
    NSLog (@ "class name:%@", Class);
}
about NULL

NULL is defined as null pointer to primitive type or absence of data, which means that the general underlying data type is empty and can be assigned to any pointer. The essence is (void *) 0, which is the literal 0 value of the C pointer.

Nsinteger *pointera = NULL;
Nsinteger Pointerb = 10;
Pointera = &pointerB;
NSLog (@ "%ld", *pointera);

we're going to try not to. Initializing the OC object with null may result in some unusual errors, primarily for the underlying data type. about Nsnull

Nsnull seems to have no specific definition (Meng), it contains the only method + (nsnull*) null,[nsnull null] is an object that represents a separate object for 0 values.

Nsmutabledictionary *dictionary = [[Nsmutabledictionary alloc] init];
NSString *nameone = @ "Allen";
NSString *nametwo = [nsnull null]; Do not use Nil,nil in the dictionary, the array has special meaning – element end tag

NSString *namethree = @ "Tom";
[Dictionary setobject:nameone forkey:@ "Nameone"];
[Dictionary setobject:nametwo forkey:@ "Nametwo"];
[Dictionary setobject:namethree forkey:@ "Namethree"];
NSLog (@ "names:%@", dictionary);

Nsmutablearray *array = [[Nsmutablearray alloc] init];
[Array Addobject:nameone];
[Array addobject:nametwo];
[Array addobject:namethree];
NSLog (@ "names:%@", array);

Nsnull is mainly used in scenarios where nil cannot be used, such as Nsmutablearray is judged by nil as an array, so if you want to insert an empty object you cannot use Nil,nsmutabledictionary is similar, We cannot use nil as an object and use Nsnull

The above is transferred from:
Text/Beichen Ming (author of Jane book)
Original link: Http://www.jianshu.com/p/2ea9c3f737ea
Copyright belongs to the author, reproduced please contact the author to obtain authorization, and labeled "Jane book author." reasons for sending messages to nil are not crash:

Send a message to nil
Sending a message to nil in objective-c is perfectly valid-it's not going to work at all. There are several patterns in cocoa that take advantage of this. The return value of a message sent to nil can also be valid:
If a method return value is an object, the message sent to nil will return 0 (nil). For example: Person * motherinlaw = [Aperson spouse] mother]; If the spouse object is nil, the message mother sent to nil will also return nil.
If the method return value is a pointer type , its pointer size is less than or equal to sizeof (void*), the integer scalar of Float,double,long double or long long, the message sent to nil will return 0.
If the method return value is a struct , as in the Mac OS X ABI function Call Guide, the message sent to nil will return 0. The values for each field in the structure body will be 0. Other structure data types will not be populated with 0.
• If the return value of the method is not the case mentioned above, the return value of the message sent to nil will be undefined.

Objective-c is based on the C language, PC, in the C language to the null pointer operation, the program will be due to cross-border access to the protection of errors and then crash, but objective-c why not crash it.

Reasons need to be found from the source code,

Here is the objc_msgsend arm version of the assembly code fragment:

In the process of ARM function call, it is generally used R0-R4 to pass the parameter and pass the return value with R0. Corresponds to Objc_msgsend, the first argument is self, and the return value is self, both in R0 (A1).

/********************************************************************
 * Idobjc_msgsend (idself, SELop, ...)

 * On ENTRY:A1 are the receiver,

 * A2 is the                  selector
 * ********************************************** /

ENTRY objc_msgsend

# Check whether receiver is nil

Teq     -A1, #0

Moveq   A2, #0

Bxeq    LR

TEQ instruction Description:

TEQ Rn, Operand2 the TEQ instruction performs a bitwise Exclusive OR
Operation on the value in Rn and the value of Operand2.

Tests whether self is empty.

moveq instruction Description:

If self is empty, the selector is also set to null.

BX directive Description:

In arm, BX LR is used to return to the calling subroutine (that is, to return to the caller), where if self is empty, return to the place where the call Objc_msgsend continues.

Anyway:

If the self argument passed to Objc_msgsend is nil, the function does not perform a meaningful operation and returns directly. understand the difference between nil,null and [Nsnull null]:

Nil is used to assign values to objects (any object in objective-c is of type ID), NULL assigns any pointers, null and nil are not interchangeable, nil is used for class pointer assignment (the class is also an object in the Objective-c). is an example of the meta-class of a class, meta-class see what Meta-class is in the objective-c. , and Nsnull is used for collection operations, in an array or dictionary where you want to add a content that is empty.
Although they represent null values, they are used in a completely different context. So in the coding, strictly according to the variable type to assign value, the correct null value assigned to the correct type, so that the code easy to read and maintain, nor easy to cause errors.
Examples are as follows:

ID object = nil;  
The object is not empty  
if (object) {  
}       
//Judgment object is null  
if (object = = nil) {  
}  

//array initialization, NULL end  
Nsarray *array = [[N Sarray Alloc] initwithobjects:@ "a", @ "Second", nil];  
Determines whether an array element is empty  
nsstring *element = [array objectatindex:2];  
if (Nsnull *) Element = = [Nsnull null]) {  
}  

//is encountered when doing the project, to determine whether the array element is empty, the following notation is invalid if (
!element)
if ([ Element length]>0) If
(element = = NULL) if
(factor = = nil)

//To determine whether the elements of a Dictionary object are empty  
nsdictionary * Dictionary = [nsdictionary dictionarywithobjectsandkeys:  
    @ "IPhone", @ "a", @ "IPad", @ "Second", nil];  
NSString *value = [Dictionary objectforkey:@ "a"];  
if ((Nsnull *) value = = [Nsnull null]) {  
}  

To sum up:
1. Nil: general assignment to empty objects;
2. Null: general assignment to a null value other than nil. such as the SEL, such as:

[Nsapp beginsheet:sheet Modalforwindow:mainwindow
    modaldelegate:nil//Use nil to point to an empty object
   didendselector:null/ /point NULL
   

 
3. When sending messages to nil, there will be no exceptions and the program will continue to execute;
4. When sending a message to a Nsnull object, you receive an exception because Nsnull has only one method: + (Nsnull *) null; "No such selector" error.
[Nsnull NULL] is an object that he uses in situations where nil cannot be used. Because nil has a special meaning in Nsarray and nsdictionary. But there are times when you really need to use such a null value, for example, in the dictionary, the phone book "Jack" under the keyword has a phone number, home address, email, etc. information, but now only know his telephone number, this information is not known to eliminate some ambiguity, it is necessary to set them to NULL, So cocoa provides a nsnull class.

[Dictionary setobject:[nsnull Null], Forkey: "Email"];
if (emailadress = = [nsnull null])
{
//to do something ...
}

Because Object-c collection objects, such as Nsarray, Nsdictionary, Nsset, and so on, can contain Nsnull objects, the program crashes if the item in the following code is nsnull:

NSString *item=[nsarray objectatindex:i];
if ([Item isequaltostring:@ "Testnumber"]) {
    //do something
}

//The following code is a common error, the release object is not set to nil, causing the program to crash.
ID Someobject=[[object alloc] init];
//...
[Someobject release];
//...
if (someobject) {
    //crash here
}

There will be a common "exc_bad_access" error, that is, a wild pointer error . Because the Someobject pointer points to the memory of the reference count is already 0, so that block of memory can not be accessed, but the someobject pointer is not set to nil, so will report a wild pointer error, the memory address of the zombie object has been unable to use. a question to look at:

The following Dealloc method, the difference between three sentences

-(void) Dealloc {
    self.test = nil; 
    [_test release];
    Test = nil;
}

Simplest: [_test release]; this sentence is to reduce the reference count of the object by 1, the so-called reference count is to see how many pointers (strong references) point to a memory entity. When released once, the corresponding pointer is reduced by one, release to 0 o'clock, indicating that the memory is actually returned to the system.

Second, self.test = nil, which involves the getter and setter methods of attributes, and when using MRC (manual reference count), the following methods are used:

The setter method for the property
-(void) Settest: (NSString *) newstring {/
    /If the new value is the same as the old value, it is not assigned the IF
    (_test!= newstring) {
        // When the new value is different from the old value, it is necessary to refer to the count minus 1
        [_test release]
        first because there is a strong reference to the old value. The new value is then assigned to the old value and cannot be directly _test = NewString, which is a shallow copy, except that the pointer address is passed, and the reference count for that block of memory does not change, which results in two pointers pointing to the memory space with a reference count of 1. There is a potential risk of causing wild pointers, so in order to avoid this problem, you need to retain to make reference count plus 1
        _test = [newstring retain];
    }

Property's Get Method
-(nssstring *) test {return
    _test;
}

So self.test = nil; this sentence becomes as follows:

if (_test!= nil) {
        [_test release];
        _test = [nil retain];
    }

The thing to do is: Retain Nil object. Before that, the old object was first given the advantage that the member variable had no chance to point to the random data, and in other ways it might point to random data. after release, if there is another way to access it, if it has been dealloc, may be crash, and point to nil, there will be no error. Nil plainly is the counter is 0, so to speak, when the real release of an object, NSLog is not able to print it points to the memory control, and when nil, it can be printed out to point to a memory space.

So it is not difficult to explain test = nil; The simple use of this can be said to create their own memory leaks, here can be understood, is equivalent to the pointer to the object directly and the object of the break. Let test directly point to nil, and the memory entity does not disappear and there is no system recycle.

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.