Several years ago, I used Objective-C for iOS development. However, I began to learn Swift when Apple released Swift two years ago. After swift1.2 was released, I officially used Swift for iOS development all the time. After that, I continued to learn Swift. With the recent release of Swift3.0, more and more people choose Swift for iOS development, which seems to be a trend. However, it is necessary for a qualified iOS developer to master OC and C language. This article is mainly to write some things that you may use but do not know the OC

  1. Object creation in oc: the +(id)alloc is used to dynamically allocate all variables and enough memory for variables defined by the parent class, and all allocated memory is cleared and set to 0
  2. You then need to call class’s -(id)init method, which sets the initial value for each variable
  3. The type returned is ID, which is a pointer that can point to any type (without the asterisk). This can be done up to a pointpolymorphismThe effect of
  4. Class files in OC: class, extension, category zjperson.h files




    Snip20160817_4.png


    ZJPerson. M file




    Snip20160817_5.png


    ZJPerson. M file







  5. The [[XXObject alloc] init] method is the same as the [XXObject new] method when no parameter is required

  6. Initialize an object with a literal, for example
    NSString *string = @"string"; == [[NSString alloc] initWithString:@"string"]; NSNumber *myBOOL = @yes; == [[NSNumber alloc] initWithBool:YES]; NSNumber * myFloat = @ 3.14 f; == NSNumber *myInt = @42; == NSNumber *myLong = @42L; = =...Copy the code
  7. Definition of multi-line macros in OC (c) (this is in swift… Add a backslash \ to the end of every line except the last




    Definition. PNG






    Using PNG.





  8. If (a==b) {} if(a==b) {} if(a==b) {} if(a==b) {} if(a==b) {} if(a==b) {} if(a==b) {} if(a==b) {} if(a==b) {} , then the comparison is whether the values are the same; If ([a isEqual: b]) {
  9. When you initialize a primitive type, try to set the initial value because the compiler assigns an initial value that is not certain, but the object type is initialized to nil by default
  10. Conditional judgment: The condition is true when the object is not nil(memory address), or when the base type is non-0, or when the bool type is true, and false otherwise
  11. Getters and setters for properties in oc @Property (nonatomic) NSString *name;

    • For example, when there is a name attribute, the default is readWrite, and the compiler automatically generates a set (setName:) and get(-(NSString *)name) method, which can be accessed through the set or get method. If declared as (readonly), only get methods will be generated
      [self setName:@"set name"]; NSString *getName = [self name]; Self. name = @"set name"; self.name = @"set name"; self.name = @"set name"; NSString *dotName = self.name;Copy the code
    • You can also override get for name. And setters (intercepting set methods)…

      For the name property, the compiler makes the synthesize a _name that allows us to access variables directly through a pointer without calling get, so variables accessed through _xx don’t call lazy load, so when we write lazy load, Instead of using self.xx(causing an endless loop), use _xx instead
      If (_name == nil) {_name = @"name"; } return _name; }Copy the code


    • And the synthesize name is something we can change ourselves, using the following syntax

      @synthesize name = customName;

    • Name cannot be accessed through __name because we specified that it can be accessed through customName

      NSString *getName = customName;

    • If, of course, you write it this way@synthesize name;, does not specify a name, so the variable name is used instead of the underscore (_)name = @"set name";😄 is cool at this point, just like swift and Java, you don’t need self,this;
  12. The oc property is atomic by default, which means thread-safe. It is not allowed to override the set and get methods because the internal setters and getters do that. However, we often use noatomic because it is faster to access. And you can override the getter and setter yourself

  13. Objects in the OC are dynamically managed and allocated to the heap so they need a pointer to point to them, so the object type needs an asteriskNSString * str;
  14. Oc in the object management is to use reference counting to management under the ARC, when there is A strong reference object pointing to the object B, B reference counting plus one, when this object is A destruction of the reference count for B minus one, until the time of the B’s reference count to zero was destroyed automatically, and this time, of course, if A strong reference to B, B also strongly references A, causing A circular reference. Neither of them will be destroyed, causing A memory leak. The solution is to mark one side as weak or unsafe_unretained(similar to swift’s [unowned self]). So improper use will cause the problem of wild Pointers)
  15. The default attribute in oc is strong, so specify weak, unsafe_unretained…
  16. NSObject * __weak someObject = [[NSObject alloc] init];This someObject doesn’t have any strong references to it, so this line of code will immediately be set to nil,NSObject * __weak someObject = self.someObject, this someObject will not be set to nil immediately after this line of code, it will be set to nil after the block of code it is in ends
  17. Assignment of attributes (shallow and deep copy)
    @property (nonatomic) NSString *name; NSMutableString * STR = [NSMutableString stringWithString:@" initial "]; ViewController *ob = [ViewController new]; ob.name = str; ---- shallow copy NSLog(@"%@", ob.name); -- initial [STR appendString:@"+1"]; NSLog(@"%@", ob.name); Ob. name = STR; ob.name = STR; Ob.name changes NSLog(@"%@", ob.name) when STR is changed; -- initial STR = [NSMutableString stringWithString:@" change "]; NSLog(@"%@", ob.name); Ob.name = STR; ob.name = STR; ob.name = STR; Change to ob.name = [STR mutableCopy]; Ob.name ---- deep copy if name is modified to copy @property (nonatomic, copy) NSString *name; Then none of the above operations will change the ob.name content ---- deep copyCopy the code
  18. The functions and properties defined by a category are no different at runtime than those defined in a native classAt runtime, there’s no difference between a method added by a category and one that is implemented by the original class
  19. However, the compiler does not automatically generate getters and setters and _XX variables to access attributes defined in the class. You need to provide getters and setters, and you need to use the runtime to bind the attribute to the class to achieve the effect of attributes defined in the native class
    /// For example, static const void *propertyKey = &propertyKey; // bind value via runtime to self objc_setAssociatedObject(self, propertyKey, value, OBJC_ASSOCIATION_RETAIN_NONATOMIC); Id value = objc_getAssociatedObject(self, propertyKey);Copy the code
  20. At the same time, classification can also be used to block code in a complex class (Swift extension can have a similar effect), so that the code can be better organized. For example, you can implement the tableView delegate and Datasource in the classification.
        @implementation ViewController(tableview)
        - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    }
    ...
    @endCopy the code
  21. However, when using categories to extend native classes in Cocoa, it is important to note that naming a function with the same name as a native existing function can lead to unexpected results (it is not certain which method will be called at runtime). Therefore, it is recommended to prefix your own function name. Just like overriding +load() to implement variousBlack magicIt is also possible that unexpected results can occur because the class’s +load method can be overridden in multiple places within the same project
  22. When I initialize my NSArray, if I passNSArray *arr1 = @[object1, object2];, you don’t have to end in nil, if you initialize it with a constructor, you pass in nil, and if the middle object has nil, then nil ends in the middle,NSArray *arr2 = [NSArray arrayWithObjects:object1, object2, object3, nil, object4, object5, nil]This ARR2 can only store the object before the first nil
  23. If you have to store it in an arraynilThen only useNSNullTo take the place of
  24. If NSArray stores objects of the NSArray, NSDictionary, NSString, NSData, NSDate, and NSNumber types, then you can write directly to disk and read data from disk to persist data[array writeToURL:fileURL atomically:YES], but if there are other types, you need to use archives to implement
  25. In for-in fast enumerations, you cannot modify (add or delete) the enumerated objects (arrays, dictionaries, collections)
  26. When you’re writing code, when you’re making conditional judgments, you often see code like thisif (a = 1){... }, the compiler will report an error, need to writeif(a == 1) {... }Of course, if you have to use an equal sign, you have to put an extra parenthesis,if ((a = 1)) {... }
  27. In fact, most of the time that’s what we use when we write conditional judgments= =Rather than=, which is only possible when we write constructors=Like this,if (self = [super init]) {... }This is not actually using=It’s true to say that the conditions are equal, but here, by[super init]The method returns an ID object that passes,self = [super init]I’m going to assign this object to self, and that’s what I’m going to use to determine if self is nil, not if self is equal to the object returned by [super init].
  28. In oc, blocks are of type object, so can be stored in NSArray… , and if the block is nil when called, the program crashes.
  29. Oc blocks capture variables by default and are not affected by subsequent changes to the original variable, e.g

    int anInteger = 42; void (^testBlock)(void) = ^{ NSLog(@"Integer is: %i", anInteger); }; anInteger = 84; testBlock(); ---- output is still 42Copy the code
  30. The second way a block captures a variable is by capturing a pointer to the variable. If the value of the captured variable changes, the value of the variable in the block also changes, but the variable needs to be marked __block, as in the above code

    __block int anInteger = 42; void (^testBlock)(void) = ^{ NSLog(@"Integer is: %i", anInteger); }; anInteger = 84; testBlock(); -- The output value is 84Copy the code
  31. With block, the ability to capture variable is a problem, a circular reference, in the ARC, as long as not using pure C language library, memory management the work doesn’t need us to complete, but the circular reference is we need to solve, the most common is when block captured the attribute of a variable is an object (method), If self is captured, then a circular reference (the block property should be marked as copy) can be created. The solution is as simple as using a pointer to a weak reference to self.__weak typeof(self) weakSelf = self;, then used in blockweakSelfalternativeselfInvoking the associated property or method does not cause a circular reference
  32. Using weakSelf can solve the memory leak problem of loop reference caused by block capturing self, but another problem is that, especially in multithreading, code may be in the blockBeing performedWhen weakSelf is used to capture a weak reference to self, the subsequent code cannot continue to execute. At this time, in order to ensure that the code in the block can execute normally even if self is destroyed, another operation we need is, When weakSelf is strongly referenced once and its reference count is increased by 1, the problem can be dealt with, which is what Apple mentioned in WWDCweak-strong-dance, the author used to write:__strong typeof(self) strongSelf = weakSelf;The important thing to understand is that the strongSelf in this block will guarantee that the code in this block will execute if the program can execute to the block. If self is destroyed before the block executes, The block will definitely not be called (the reference count of the block is already 0).

I usually have a demo in my article, but I don’t have one in this article because it’s just a little bit of grammar