In this article, Objective-C discusses the core syntax of the language. This section describes some specific syntaxes. As you expected, definitions and classes are involved.
BKJIA recommendation topic: iPhone application development
Class is not special
In Smalltalk, classes are objects with some features. The same applies to Objective-C. A class is an object that responds to messages. Both Objective-C and C ++ separate object allocation and initialization.
In C ++, objects are allocated through new operations. In Objective-C, such an operation is to assign a message to the class by calling malloc () or an equivalent.
In C ++, the initialization is done by calling a function with the same name as the class. Objective-C does not distinguish the initialization method from other methods, but the default initialization method out of Convention is initialization.
When you declare a method for the instance to respond, the Declaration usually starts with "-" and "+" is used as the class method. It is common to use some prefixes for these messages in this document, so you can also say that + alloc and-init imply that alloc is passed to a class, and init is passed to the instance.
Classes in Objective-C are all object factories, just as in some other object-oriented languages. Most classes do not need to implement + alloc on their own, but inherit from their parent classes. In NSObject, in most Objective-C Programs, the parent class + alloc method call + allocWithZone:. Makes NSZone a parameter. a c structure contains some policies for object allocation. Looking back, in 1880s, when Objective-C was used in NeXTstep to implement the GUI of a device driver and a CPU machine with only 8 MB memory of 25 MHz, NSZone was very important for optimization. At the same time, this is more or less ignored by Objective-C programmers. (It is likely to become popular and more common like the NUMA architecture .)
One of the many outstanding features is that the object creation semantics is defined by the database and the language is not the idea of class clusters. When you send a-init message to an object, it returns an initialization object. This may be the object you sent the message to, but not necessarily. This is consistent with other initialization programs. It is very likely that some special subclasses of public classes are more effective on different data.
The general method for implementing this feature is isa-swizzling. As I mentioned above, the Objective-C object is a C structure. The first element of these structures is a pointer to a class. This element is accessible, just like other instance variables; you can change the class of an object by assigning a new value at runtime. Of course, if you have different la s for object class settings in the memory, these settings may be severely incorrect.
However, you can use a parent class to define the layout and behavior through a subset set. For example, this technology is used to standardize the string class (NSString ), it has various examples for different text character sets, static things, and others.
Because classes are objects, you can operate on them like operation objects. For example, you can place them in a collection. This format is used when some input events need to be processed by instances of different classes. You need to create a directory ing event named to the class, and then instantiate an object for each input event. If you do this in a library, it allows code users to easily register their own handles.
Type and pointer
Objective-C does not publicly allow objects to be defined on the stack. But it is not true-it is very likely to define objects on the stack, but it is difficult because it breaks the assumption of memory management. As a result, each Objective-C object is a pointer. Some types are defined by Objective-C; these types are defined as C Types in the header.
The three most common types in Objective-C are id, Class, and SEL. Id is the pointer to an Objective-C object. It is equivalent to void * in C. You can map any object pointer type to it and map it to another object pointer type.
You can send any message to the id, but if not, a runtime exception is returned.
Class is a pointer to the Objective-C class. Class is an object, so you can also receive messages. A class name is a type that is not variable. The identifier NSObject is the type of an NSObject instance, but it can also be used as a message recipient. You can obtain a class as follows:
- [NSObject class];
Send a + class message to the NSObject class, and return a class structure pointer pointing to the class.
This is very useful for our review [FS: PAGE], as we can see in the second part of this series.
The third type SEL represents a selector-an abstraction that represents the method name. You can directly create a function by @ selector () at compile time, call the library function at runtime through a C string, or use the OpenStep NSSelectorFromString () function, this function provides a selector for the Objective-C string. This technology allows you to call methods by name. You can use dlsym () in C, but it is very different in C ++. In Objective-C, you can do the following:
- [object perfomSelector:@selector(doSomething)];
This is equivalent to the following:
- [object doSomething];
Obviously, the second format is faster, because the first one transmits two messages. Later, we will see some details processed by selector.
C ++ does not have the same type as id. Because objects can always be typed. In Objective-C, you can select a type system. The following two types are valid:
- id object = @”a string”;
- NSString *string = @”a string”;
A constant string is actually an instance of the NSConstantString class, And the NSConstantString class is a subclass of NSString. Reference it to NSString * so that the message type is checked during compilation and public instance variables are stored (this is never used in Objective-C ). Note that you can change this setting as follows:
- NSArray *array = (NSArray*)string;
If a message is sent to an array, the compiler checks the messages that NSArray can receive. This is not very useful because the object is a string. If an NSArray or NSString message is sent, it may be useful. If the NSString message you sent is not implemented, an exception will be thrown.
It seems strange to emphasize the difference between Objective-C and C ++. Objective-C has the type-Value Syntax, while C ++ has the type-variable syntax. In Objective-C, the object type is a proprietary property of the object. In C ++, the type depends on the type of the variable.
In C ++, When you assign a pointer to an object to define a pointer to the parent class in a variable, the two pointers may not have the same value (this can be achieved through multi-inheritance, objective-C does not support this type .)
Definition class
The Objective-C class defines an interface and an implementation part. It is similar to C ++, but the two are slightly mixed.
Interfaces in Objective-C only define bits and explicitly need to be made public. For implementation reasons, this includes private instance variables in most implementations, because you cannot inherit a class unless you know how big it is. Some recent implementations, such as Apple's 64-bit runtime, do not have such restrictions.
The Objective-C object interface is as follows:
- @interface AnObject : NSObject
-
- {
-
- @private
-
- int integerivar
-
- @public
-
- id anotherObject;
-
- }
-
- + (id) aClassMethod;
-
- - (id) anInstanceMethod:(NSString*)aString with:(id)anObject
-
- @end
-
The first line contains three parts. The identifier AnObject is the name of the new class. The name after the colon is NSObject. (This is optional, but every Objective-C object should expand NSObject ). The name in the brackets is the protocol-similar to the interface in Java-implemented through classes.
Just as C ++ instance variables (fields in C ++) can access modifiers, unlike C ++, these modifiers are prefixed with @ to avoid conflicts with C identifiers.
Objective-C does not support multi-inheritance, so there is only one parent class. Therefore, the layout of the first part of the object is always the same as that of the parent instance. This is often defined as dynamic in the past, which means that changing the instance variables in the class requires recompilation of all its subclasses. This limitation is not required during newer runtime, and the cost for accessing instance variables is slightly higher. Another influence of this decision is one of the other features of Objective-C.
- struct_AnObject
-
- {
-
- @defs(AnObject);
-
- };
-
@ Def indicates that this structure is inserted to all the domains of a specific object. Therefore, struct_AnObject and AnObject instances share the same memory structure. For example, you can use this rule to directly access instance variables. A common usage is to allow the C function to directly operate the Objective-C object, which is based on the performance.
As I mentioned earlier, another thing related to this feature is that you can create an object on the stack. Because the structure and object share the same structure in the [FS: PAGE] memory layout, you can create a structure and set its pointer to the correct class, map a pointer to an object pointer. Then you can use it as an object, although you have to be careful that there is nothing to keep the pointer out of bounds. (In the real world, I have never used this method. It is only theoretically possible .)
Unlike C ++, Objective-C does not have private or protected methods. Any method on the Objective-C object can be called by other objects. If you do not declare a method in the interface, it is informal and private. You will receive a runtime warning: the object does not respond to this message, but you can still call it.
The interface is similar to the header declaration in C. But it still requires an implementation. It is not surprising that it can be defined using @ implementation.
- @implementation AnObject
-
- + (id) aClassMethod
-
- {
-
- ...
-
- }
-
- - (id) anInstanceMethod:(NSString*)aString with:(id)anObject
-
- {
-
- ...
-
- }
-
- @end
-
Note that the parameter type is specific, in parentheses. This is to display the value ing to the type from the C reuse ing syntax; they may not be the type. Exactly apply the same rules when ing. This means that ing between incompatible Object Pointer types will cause a warning (not an error ).
Memory Management
Traditionally, Objective-C does not provide any memory management. In earlier versions, the object class implemented a + new Method to call malloc () to create a new object. After this object is used up, A-free message is sent. Any object inherits from NSObject to respond to a-retain and-release message. After using this object, you can send a-free message. Reference computing is added in OpenStep.
Every object inherited from NSObject responds to-retain and-release messages. If you want to keep a pointer to an object, you can send a-retain message. After use, you can send a-release message.
This design has a subtle problem. Generally, you do not need to keep a pointer to an object, but you do not want to release it. In a typical example, when returning an object, the caller must keep the pointer to the object, but you do not want to do so.
The solution to this problem is the nutoreleasepool class. With-retain and-release added, NSObject also responds to the-autorelease message. When you send one of them, it is registered with the current Auto Release pool. When the pool object is deregistered, it sends a-release message to each object, and the object receives the-autorelease message before this. In the OpenStep application, An NSAID utoreleasepool instance is created at the beginning of the loop and destroyed at the end. You can also create your own instance to automatically release objects.
This mechanism reduces the number of copies required for C ++. In fact, this is not worth doing. In Objective-C, the variability is the object attribute, not a reference. In C ++, there are constant pointers and constant pointers. You cannot call the constant method on a constant object. This does not ensure that the object will not be changed-just because you don't want to change it.
In Objective-C, a normal pattern defines a constant class and a variable subclass. NSString is a typical example;
It has a variable subclass NSMutableString. If you get NSString and want to save it, you can send a-retain message and save the pointer without the need to copy the message. On the contrary, you can send a + stringWithString: message to NSString. Whether the parameter is variable or not, the system checks and returns the original pointer.
During Apple and GNU running, Objective-C supports storage-based garbage collection, which avoids the need for-retain and-release. Language appending in existing frameworks is not always well supported, and you need to be especially careful when using it.
Summary
Now that we have browsed the core of Objective-C language, we will see more advanced topics in this section.