Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
113 views
in Technique[技术] by (71.8m points)

ios - Why Some Variables are Declared with an * Asterisk in Objective-C

I am just starting to learn Objective-C. I am confused to see that some types of variables are sometimes declared with an * asterisk, others are not. For example these are delcared with a *:

@property NSString *firstName;
NSString * mainString = @"Hello World!";
NSNumber *longNumber = @42l;
NSArray *unsortedStrings = @[@"gammaString", @"alphaString", @"betaString"];

And these are not:

int someInteger = 42;
NSInteger anInteger = 64;
id firstObject = @"someString";
NSRange substringRange = [mainString rangeOfString:@"long"];

I found this explanation from Apple's documentation: https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/ProgrammingWithObjectiveC/WorkingwithObjects/WorkingwithObjects.html#//apple_ref/doc/uid/TP40011210-CH4-SW1

Both these properties are for Objective-C objects, so they use an asterisk to indicate that they are C pointers.

But this explanation is too general and vague for me to understand the concept. I know type * means it is a pointer type, and this type stores pointers of that type. But why some types are declared with *, others are not?

question from:https://stackoverflow.com/questions/65865716/why-some-variables-are-declared-with-an-asterisk-in-objective-c

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

The int type is not object. It is a C language “primitive data type”. You generally interact with primitive C data types directly. E.g.,

int i = 0;   // it’s now `0`
i = 42;      // it’s now `42`

The NSInteger is just an alias for another primitive data type, long. The NSRange is a struct (thus, also not an object), so the same rule applies. So, for basic interaction with these primitive data types, no * pointer reference is generally needed. (There actually are times you also deal with pointers to primitive data types, but that is beyond the scope of this question.)

But NSString, NSNumber, and NSArray, however, are objects, so you must use pointers when declaring them.


Note, you've included id in the latter list where * is not used:

id firstObject = @"foo";

Be very careful. This actually is a bit misleading, because firstObject actually is a pointer to the @"someString", a NSString object. The id is an exception to the way we generally declare pointers with * and is discussed in Objective-C is a Dynamic Language), “The id type defines a generic object pointer.”

It’s analogous to declaring a NSString pointer, but “you lose compile-time information about the object”. Compare the id pointer to the NSString * to the following syntax:

NSString *secondObject = @"bar";

This latter secondObject is NSString * pointer, but because we explicitly declared it as a NSString * pointer, the compiler knows that you are dealing with a string (thus the compiler can perform greater validation regarding your subsequent use of that pointer). With id, you do not enjoy this compile-time validation.

For example, here are two invalid attempts to call removeObject method on two NSString objects. NSString has no such method. The NSString * reference provides useful compile-time error message that id does not afford us:

enter image description here

Now, if you used the id type and tried to run that code, it would crash when it attempted to call removeObject on firstObject. But, where possible, it is much better to have the compiler tell us about the error during compile-time, rather than at run-time.

So the id pattern should be used sparingly, only when you really need Objective-C’s dynamic type behaviors.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...