The last time I read this book, I hurried through it. Recently I was not very busy. I revisited it and wrote my notes ~..
If you are interested, you can buy one. I think this book is quite good.
Because most of them are written on mobile phones when they are in the car, there are very few codes and images.
1. Try to use Forward Declaration to delay the time for introducing header files, which can reduce the Compilation Time.
2. use arraywithobjects :.... if a variable is empty, it will be automatically terminated, and the subsequent variables will not be added, and no error will be reported, resulting in data inconsistency, therefore, try to use the literal syntax to create related objects, reduce errors and reduce the amount of code
3. All objects created using the literal are immutable. To obtain a mutable object, you must call the mutablecopy method.
4. Static declared variables (between imple block and interf block) are only visible in the current compilation unit. If static is not added, the compiler creates an external symbol for it. If a variable of the same name is declared in another compilation unit, an exception is thrown.
5. When defining constants, we should use less preprocessing commands and more static const commands. Such constants carry type information to reduce the chance of errors. In addition, if a variable is declared as static const, the compiler will not create a symbol for it, but directly replace it.
6. if you want to allow external use of your defined constant variables, you need to use the header file declaration extern nsstring * const variable to write nsstring const variable = @ "kkkkk" in the implementation file ", in this way, you can access this variable externally. In addition, it is best to use the class name to start with this type of variable name for global access to avoid conflicts with repeated declarations.
7. when enumeration is used, if enumeration does not need to be combined, ns_enum should be used to define enumeration. In this form of enumeration compilation, related macro definitions will be automatically added, use the new syntax in the new environment and the old syntax in the old environment.
8. If you want to use the combined enumeration, it is best to use ns_options to define it. In C ++, the obtained variable after enumeration operation should be its underlying data and should not be an enumeration variable. Therefore, to convert the variable, you can use the above method to automatically determine whether display conversion is required.
9. the C ++ access member variable is accessed by the offset determined during the compilation period. If a variable is added, the variable located after it will encounter an access error, because the offset has been determined, an error occurs when the offset is increased. The OC method is to store the offset in the Class Object and go back to the tired object for query during access. Therefore, if a new variable is added, the access is always correct. See page 22 (ABI and API)
10. @ Synthesize Method life = variable names automatically generate get and set methods during compilation. The variable system declared by @ dynamic does not create instance variables and access methods for them, in addition, when the compiler accesses the attribute code, the compiler will not report an error even if it does not find the stored method, because it is believed that it can be found at runtime, coredata. this technology is used because its attributes come from databases, not instance variables.
11. attributes are enclosed in parentheses. attributes are classified into four types: ① atomicity, ② read/write permissions, ③ memory management semantics, and ④ method name.
12. Memory Management semantics weak strong assign copy unsafe_unretained (this semantics will not be automatically cleared when the object it points to is destroyed, weak will)
13. When writing the initialization method with parameters, If you directly assign values to the attribute, pay attention to the memory management semantics when assigning values, which is defined as copy. Remember to use cooy.
14. Direct Access to instance variables within a class object is faster than point-based access because direct access is not distributed. Direct access does not call the access method. If the access method is processed, you must note that direct access does not call the memory management semantics. Direct access to variables does not trigger KVO. Attribute access helps you troubleshoot errors.
The two access mechanisms have their own advantages and disadvantages. The alternative method is to directly access the access when obtaining the access and call the method when setting the access (ensure the memory management semantics)
15. If lazy loading is written in the get method, you should use the dot syntax to access the variables. In the initialization method, you should always directly access the variables. Because, this cannot be understood.
16. thrown an exception nsexception raise: format:
17. isequal can be called to determine equivalence if it is the same class: if it is a comparison string equivalence, a specific method should be used to reduce performance consumption. Arrays and dictionaries also have their own equivalence comparison methods.
18. if you want to write the same-sex Judgment Method for the defined class, you should also re-write the isequal method to determine whether it is the class. If it is the class, you can call your own judgment method, if not, it is determined by the parent class.
If the object has its own specific ID, you can directly determine the ID.
19. The class family can hide the implementation details behind the abstract base class. uibutton is one of them. When defining a class family, you generally need to provide the enumeration subclass and the class method for creating the subclass.
20. iskindofclass should be used to determine the class family: If the comparison is to determine that the class instance should use ismemberofclass
21. OC allows an object to be dynamically associated with other objects. The objc_setassociatedobject () function can set an associated object for an object. The objc_getassociatedobjects () function can obtain the key objects stored in the previous step based on the given key. Objc_removeassociatedobject () This method can remove the specified correlated object
However, the associated object should not be abused, because it is very likely that the retention ring will be introduced, and it is difficult to debug and solve the problem.
22. Methods in OC will eventually be converted to the underlying objc_msgsend () method implementation. Both the selector and parameter are called messages. objc_msgsend () can accept two or more parameters. Objc_msgsend () calls an appropriate method based on the receiver and the selected sub-type. This method searches for the method list in the class to which the receiver belongs. If it is found, it is executed, if this method is not found, search up along the inheritance system of the class, and wait until the method is found. If it is not found all the time, the message forwarding operation will be executed. There seems to be many steps to execute a method, but after executing a method for the first time, objc_msgsend () will cache the matching results in the quick ing table, but it is not as fast as static function binding.
23. objc_msgsend_stret () is used to process the returned amount as a struct. This function can only process the struct that can be accommodated by the CPU register. If the struct is too large, it will be called by another function.
Objc_msgsend_fpret () is a floating-point method for processing the returned data. Objc_msgsendsuper () is used to send messages to the superclass.
The Optimization Technology of the End call can optimize the message mechanism. if and only when the last row of a message calls another function, it will not return another value.
24. Message Forwarding is divided into two phases. First, the receiver is asked to check whether the method can be dynamically added to process this unknown sub-selection. The first stage of the response is complete. At this time, the system will request the receiver to check whether other objects can process the message. If yes, the receiver will process the message. If not, the complete message forwarding mechanism will be enabled, at this time, the system will encapsulate the message-related details into the nsinvocation object, and once again give the recipient a chance to try to solve the current message.
25. After an object receives a message that cannot be interpreted, it first calls the following method:
-(Bool) resolveinstancemethod :( SEL) Selector
If you are looking for a class method, you will call-(bool) resolveclassmethod :( SEL) selector if you cannot find it.
If the above method returns false, it means that the class will not add a new method to process the above message and will go to the next step.
If no is returned for the above method, this class will not add a method to process this message. The next step is to call
-(ID) forwardingtargetforselector :( SEL) Selector
The returned value indicates that the message will be sent to it for processing. This feature can be used to simulate multiple inherited features and specify the objects to be executed within the class, in the outside world, it seems that this object is actually handled by its internal object.
If the returned nil indicates that there is no object in the object that can process the modified message, the runtime system will call the complete message forwarding for execution.
-(Void) forwardinvocation :( nsinvocation *) Invocation
This also specifies the recipient to execute this method. If this method is implemented, the call operation should not be processed by this class, you need to call a method with the same name as the super class. If the method still cannot be processed after tracing to the nsobject class, the doesnotrecognizeselector will be called to throw an exception.
P49 examples
Class_addmethod () can be dynamically added
26. When the method is executed, the system will go to the method list of the class to find the method. These methods are expressed as imp pointers, for example
You can change the method name and function ing table to implement method interchange.
Method_exchangeimplementations () This method can swap two functions
Method M1 = class_getinstancemethod (you can obtain the corresponding method.
After interchange the custom method with the system-defined method, the Black Box log function can be added. Do some things in the custom method, and then call the custom method, which may produce an endless loop, however, it should be noted that they point to interchange during the runtime, and the original method is actually called during the call.
26. each class has an ISA pointer, and the class is also an OC class object. The ISA pointer of the Class Object points to a Meta class to express the metadata of the Class Object, class methods are defined as follows:
27. because OC does not have a namespace, it is prone to conflicts during class naming. This problem is generally solved by prefix. Apple claims that it reserves the right to use the two-letter prefix, generally, the framework provided by OSS is a prefix of two letters, so if your project uses the naming method of two letter prefixes, there may be conflicts with the framework. In addition, the top-level symbols of C language functions and global variables must be prefixed to avoid conflicts. 28. generally, during object initialization, a part of data (uitableviewcell) is required ). therefore, we generally provide an all-around Initialization Method for other initialization methods to call this initialization method. data-related storage is executed in the full-volume initialization method. To change the storage mechanism, you only need to change this method. this facilitates program control. If you want to force the use of your custom all-powerful initialization method, you can write an exception in the non-controllable methods such as init @ throw [nsexception exceptionwithname: reason: userinfo:]. you can also write the default value in the init method. If there is an inheritance system, The call chain of All-Around initialization methods must be maintained to ensure program robustness. in addition, if the full-purpose Initialization Method of the parent class is not applicable to child classes (Rectangles and squares), you should rewrite this method and throw an exception 29 in it. if you need to frequently view information about a class, we need to rewrite the description method of the class [nsstring stringwithformat: @ "% @: % P ..... ", [] If you often want to view the object information in the debugging box, you need to override the debugdescription method. In addition, nsarray and nsdictionary do not call the description method but call-(nsstring *) descriptionwithlocale :( ID) locale Method 30. try to create immutable objects. if an attribute can only be used for internal modification, change its readonly attribute to readwrite in class extension. instead of making the variable collection public as an attribute, you should provide relevant methods to modify the variable collection 31 in the object. add the prefix letter + _ to the private method used inside the class. Do not directly use the underline, which is easy to conflict with what Apple provides. to add a prefix to a private method, you can clearly see the difference and notice that the methods used by the public are not easily changed. 32. OC is not exceptionally secure by default. If you want to use the exceptional security code, you need to enable the compiler flag-fobjc-arc-exceptions even if you do not use it ..... OC's current practice is to throw an exception only in rare cases. After an exception is thrown, you do not need to consider the restoration problem. At this time, the application should also exit. The exception is an extremely serious error, for example, if you write an abstract class, the correct method to use it should be to integrate a subclass from it, and then use this subclass. For methods that must be overwritten by the write silently, you can throw an exception in the parent class, in this way, the subclass must be overwritten. Otherwise, non-fatal errors cannot be executed. Nil/0 can be returned or nserror can be used. If the initialization method cannot be used to initialize the current instance based on the input parameters, therefore, nil33. to copy a custom object, you must implement the nscoying protocol. if custom objects are divided into variable versions and immutable versions, the nscopying and nsmutablecopying protocols must be implemented at the same time. In general, all objects executed are shortest copies, deep copy requires some settings or custom settings (you can also use runtime to implement deep copy) 34. OC does not support multi-inheritance, but supports protocols (similar to interfaces in Java). Communication between objects is often required. One of the communication modes between objects in OC is the delegate mode and the data source (datasource) and the proxy (delegate) can process data and events separately, which can achieve good decoupling effect ., the naming method of the proxy protocol is generally class name + delegate, and its method name is generally the class name with the removal of prefix + related operation name. the proxy member variables of this class are generally declared as weak; otherwise, a retention ring is easily generated. (for example, for tableview, if the delegate of tableview is strong, it retains its controller, and the Controller also has the strong reference of tableview, which produces a retention ring) 35. the methods in the proxy protocol sometimes do not require the proxies to be fully implemented. Only part of them can be implemented. Add the @ optional keyword to the method declaration to mark it as an optional implementation, and add @ required to mark it as a required implementation, generally, when calling an optional method, we need to check whether the proxy object has implemented the method to be called (using responsetoselector ). 36. if an Optional Protocol method needs to be called frequently, "bitfield" can be used to identify whether the agent has implemented the relevant method, because whether the query method is implemented is a relatively time-consuming operation, if the execution frequency is high, saving with the flag can save performance overhead. struct data {unsigned int fileda: 8; unsigned int filedb: 4;
Unsigned int filedc: 2;
Unsigned int filedd: 1;
} Fielda occupies 8 binary bits in the struct, which can represent 0 ~ Value Between 255, while fieldd can represent 0-1struct {unsigned int didreceivedata: 1; unsigned int didfailedwitheorror: 1;
Unsigned int didupdateprogressto: 1;
} _ Delegateflags; then override setdelegate: method. When setting the proxy, query it again to see if the proxy object has an optional method and sets the flag, follow the flag bit to check whether the relevant method can be called 37. the classification mechanism can be used to divide the implementation code of the class into small pieces that are easy to manage, and the classification information is printed during debugging, which is easy to debug. if some methods do not need to be published, they can be written in the private category and no longer published in the header file (static library) 38. if there is a method of the same name in the two categories, the classification will not report an error, and the last loaded method will prevail according to the loading order, overwrite the previously loaded method. therefore, it is best to add a prefix when writing a method, which will greatly reduce the coverage of the classification method ,... In addition, the classification method has a higher priority than the one directly written in the class. If you write the same method as in the class, the classification method will overwrite the method 39 in the class. generally, do not add attributes to a category. Although you can use the associated object method to access attributes in a category, this type of thing is insecure and may lose the memory management semantics. sometimes, if the attributes in a category are independent, it can be defined without interacting with the data in this category. however, even such a page is better not to use category attributes. 40. class-continuation is a special type of classification, also called class extension. This type of classification does not have its own name. It is directly written in the class implementation file, and the attributes written here will not be made public, it can be used to declare or store private variable methods (in fact, there is no real private method in OC, and any variables and methods can be accessed using the runtime set) 41. if OC ++ code is used in the OC class, if this header file is introduced, the file will also be compiled in C ++ mode (Suffix. mm. h introduces the C ++ header file. In this case, an OC interface is exposed to the outside, hiding the implementation details. webKit, coreanimation, and other frameworks both use this method. Another usage of class extension is to change the attribute declared as readonly in the header file to readwrite, so that this attribute can be read and written within the class, the external class is read-only. If you want to follow a private or protocol that does not need to be known to the outside world, the class extension can follow 42. with arc, the system can automatically detect the correct retain release operation when the code is generated. Otherwise, the system will automatically cancel the operation. using Arc to call the objc_autoreleasereturnvalue method, this method can detect a piece of code to be executed after the returned object. If there is a correct operation with the execution just now, A flag is set for a global data structure (related to the data structure root processor) without performing the release operation. objc_retainautoreleasedreturnvalue is much faster than executing retain and release, so it is best to use arc 43. if an object is returned starting with alloc, new, copy, and mutablecopy, the system does not perform any operations. If it starts with another form, the system automatically calls autorelease 44 on the returned object. what should be done in the dealloc method is to release the reference pointing to other objects and cancel the original subscribed key value observation and notification. Generally, do not do other things, because at this time, the object's life is nearing completion. If the object holds scarce resources such as file descriptors, you should write a special method to release such resources. Such a class should be agreed with its users, the close method must be called after resources are used up. you can add a flag attribute to the class. If the close method has been executed, the flag position is 1, and then the dealloc determines whether the flag bit is 1, if it is not set to 1, an exception should be run. asynchronous tasks should not be called in dealloc. methods that can only be executed under normal conditions should not be called in dealloc. when capturing exceptions, You must clean up the objects created in try. by default, arc does not generate the cleanup Code required for exception handling. It can enable the compiler flag, but this will increase the application and reduce the running efficiency by 46. reasonable Use of the automatic release pool can reduce the program's memory peak 47. when writing a program, it is best to enable the zombie object debugging function, so that the hacker can help the master quickly locate the crash. If the system finds that an instance starting with _ nszombie -- sends messages, it will interrupt 48. class linoleic = object_getclass (p); object_getclass () can obtain information about the class.
Class superlinoleic = class_getsuperclass (CIA); class_getsuperclass () can obtain the parent class information of a class;
Const char * name = class_getname (CIA); class_getname (CIA) can get the class name of a class.
Class basezombi = objc_lookupclass ([@ "_ nszombie _" utf8string]); objc_lookupclass can be found
Does the current system have the specified class?
Zob = objc_duplicateclass (basezombi, [@ "_ zombie_person" utf8string], 0 );
Objc_duplicateclass can dynamically add classes to a specified template.
Objc_destructinstance (p); objc_destructinstance can destroy an instance;
Abort (); can interrupt Application Execution
49. we should do our best to avoid using retaincount, because you don't know how many automatic release pools there are outside of him, and the number of times the system will perform the release operation for this object. 49 block will retain the objects used in the block (whether the method or variable). If the block is inside the object, and the block uses the class member variables, whether or not self is used. The block will retain self, because even if you use _ xx to directly access the member variable, it is actually accessed through self-> xx 50. block is actually an OC class, but it is a special class. Block classes are divided into three types: Stack block stack block and global blockblock, which are created on the stack by default, the copy function is used to copy the block objects to the stack. The block objects under MRC also need to be manually managed.
Block_copy (<#... #>) block_release (<#... #>) performs the copy and release Operations respectively;
A global block is a block that does not access external variables. The copy operation is null for such a block, because it remains unchanged and does not need to be copied (it can be executed by a provisioning program)
51. If a retained ring must be generated, the reference of a certain party should be left blank by using methods such as xx = nil after the function is executed to cancel the retained ring. Many network frameworks are retained before release.