Add 3 chapter notes and update chapter index

This commit is contained in:
√(noham)²
2026-02-22 22:04:06 +01:00
parent 898f333ab0
commit fcdd5b9db2
4 changed files with 345 additions and 2 deletions

88
Chapter1 - iOS/1.1.md Normal file
View File

@@ -0,0 +1,88 @@
# Image Assets Optimization for Project Size
> A small iOS project with many features can grow large in size. Under an Xcode project, image assets can take up a lot of space, and if an app needs a one-click skin/theme change, imagine how many images that requires. Each set of images also needs 1x, 2x, 3x, etc.
## Introduction
IconFont technology originated in the web field from Web Font technology. Over time, web design became more beautiful. But system-installed fonts on computers could no longer satisfy designers, so Web Font technology was born. An English character font set is not large; by downloading fonts over the network, webpages can be rendered. With Web Font technology, designers gained much more freedom.
In web design, icons need to adapt to multiple resolutions, and each icon would require a separate network request. Someone thought to use the Web Font approach to solve both problems: make vector icons into a font, so a single network request suffices and the icons scale cleanly. Another way to solve this is using sprite images.
The web community has used IconFont-like techniques for years—when I first encountered Bootstrap in 2015, Font Awesome was very popular. Recently IconFont technology has been applied to iOS image assets. I had some time to research and整理 (organize) it, and I record my learning here.
## Advantages
* Reduce size — font files are smaller than images
* Icon fidelity when scaling — solves 2x/3x and future n× image issues
* Easy to change color and size, image reuse
## Disadvantages
* Only suitable for
`single-color icons`
* Using Unicode characters is hard to understand
* Need to maintain the font library
There are many tutorials online about how to make IconFonts; I won't discuss that here.
## How to use
1. First pick some rich resource sites. I've used Alibaba's IconFont for years and didn't research others, so I'll use Alibaba's product here. Address: http://www.iconfont.cn/plus
2. Open the site and select suitable icons into the cart, as shown:
![](../assets/2017-05-28-iconfontPickUp.png)
3. After selecting, view the cart and click to download the code.
4. Open the downloaded file; its structure is as follows. In iOS development we use the Unicode form of IconFont, so open demo_unicode.html
![Downloaded file structure](../assets/2017-05-28-iconfontWorkDirectory.png)
**Note:** Create UIFont using the font's PostScript name, not the file name; text values are 8-digit Unicode characters. We can open demo.html to find the HTML entity Unicode code for each icon. For example: the icon "店" corresponds to HTML entity Unicode code: 0x3439. Converted it becomes: \U00003439 — replace 0x with \U and pad with zeros to reach 8 characters.
# Using IconFont in Xcode
Initial attempt usage
1. First see how to use IconFont simply.
2. Add the downloaded **iconfont.ttf** into the Xcode project and ensure it's included in Build settings.
![Xcode inclusion check](../assets/2017-05-28-iconfintWorkSetting.png)
3. How to use?
```objective-c
NSMutableAttributedString *attributedStr = [[NSMutableAttributedString alloc] initWithString:@"\U0000e696 \U0000e6ab \U0000e6ac \U0000e6ae"];
[attributedStr addAttribute:NSForegroundColorAttributeName value:[UIColor redColor] range:NSMakeRange(0, 1)];
[attributedStr addAttribute:NSForegroundColorAttributeName value:[UIColor orangeColor] range:NSMakeRange(3, 1)];
[attributedStr addAttribute:NSForegroundColorAttributeName value:[UIColor blackColor] range:NSMakeRange(9, 1)];
self.label.attributedText = attributedStr;
[self.view addSubview:self.label];
#pragma mark - getter and setter
-(UILabel *)label{
if (!_label) {
_label = [[UILabel alloc] initWithFrame:CGRectMake(100, 100, BoundWidth-200, 40)];
_label.font = [UIFont fontWithName:@"iconfont" size:24];
_label.textColor = [UIColor purpleColor];
}
return _label;
}
```
#### Further encapsulation for easier use
Generating a UIImage from IconFont only requires LBPIconFontmake(par1, par2, par3), where par1: the iconfont Unicode value; par2: image size; par3: image color. LBPIconFontmake is a macro: #define LBPIconFontmake(text,size,color) [[LBPFontInfo alloc] initWithText:text withSize:size andColor:color].
```objective-c
self.latestImageView.image = [UIImage iconWithInfo:LBPIconFontmake(@"\U0000e6ac", 60, @"000066") ];
```
![Encapsulated project structure](../assets//2017-05-28-iconfont.png)
1. LBPFontInfo encapsulates font information.
2. UIColor+picker sets color from a hex string.
3. LBPIconFont registers the IconFont into the system and uses it.
4. UIImage+LBPIconFont provides a UIImage category for using IconFont.
# Demo repository
https://github.com/FantasticLBP/IconFont_Demo

165
Chapter1 - iOS/1.2.md Normal file
View File

@@ -0,0 +1,165 @@
# Understanding Initializers
## Initializers
* The internal implementation of the new method is to call alloc first, then call init.
* alloc: Sends the alloc message to a class; alloc returns an instance of that class.
* init: An instance method whose role is to initialize the object.
* Steps to create an object: first use alloc to create an object, then use init to initialize it before using the object.
* Using an uninitialized object is dangerous.
* init method: Purpose — initialize the object and set initial values; this is called a constructor (initializer).
## Overriding init
* If you want the created object's properties to have values other than the default initialization values, you need to override init.
* Rules for overriding init:
* You must first call the superclass's init method (because initialization of the current class proceeds through [super init]), and assign the returned value to self.
* Calling init may fail; if it fails, return nil.
* Check whether the superclass initialized successfully. If self != nil, initialization succeeded.
* If initialization succeeded, initialize the current class's properties.
* Finally return self.
#### Clarifications:
1. Why call the superclass init method?
1. The current object has an isa pointer; the isa pointer is set through the superclass's init.
2. You need to ensure that the superclass's properties are also initialized.
2. Pattern for overriding init:
```
-(instancetype)init{
if (self = [super init]) {
// todo: custom property initialization
}
return self;
}
```
```objc
// Person
#import <Foundation/Foundation.h>
@interface Person : NSObject
@property NSString* name;
@property int age;
-(void)sayHi;
@end
#import "Person.h"
@implementation Person
-(void)sayHi{
NSLog(@"Hi");
}
-(instancetype)init{
self = [super init];
if (self) {
self.name = @"杭城小刘";
self.age = 22;
}
return self;
}
@end
// Test
Person *p1 = [[Person alloc] init]; // p1.name = "杭城小刘", p1.age = 22;
Person *p2 = [Person new]; // p2.name = "杭城小刘", p2.age = 22;
```
If two classes have a composition relationship and one property is an object of another class, that property defaults to nil when the containing class is initialized. How to initialize it?
```
-(instancetype)init{
self = [super init];
if (self) {
self.name = @"lbp";
self.age = 22;
self.pig = [[Pig alloc] init];
}
return self;
}
// Test
Person *p1 = [[Person alloc] init]; // p1.pig != nil
```
## Custom initializers
* Current situation: Although each created object's properties are not the default values, every initialized object has the same values.
* Requirement: Allow callers to decide the property values when instantiating.
* Solution: Custom initializer.
* Rules for custom initializers:
* The return type should be instancetype.
* The method name must begin with initWith.
* The implementation is similar to init.
* Note: You cannot use new to call a custom initializer. (new performs alloc then init; default init assigns the default property values.)
```
-(instancetype)initWithName:(NSString *)name andAge:(int)age{
if (self = [super init]) {
self.name = name;
self.age = age;
}
return self;
}
```
```objc
// Person
#import <Foundation/Foundation.h>
@interface Person : NSObject
@property NSString* name;
@property int age;
-(instancetype)initWithName:(NSString *)name andAge:(int)age;
@end
#import "Person.h"
@implementation Person
-(instancetype)init{
self = [super init];
if (self) {
self.name = @"lbp";
self.age = 22;
}
return self;
}
// You cannot assign to self outside of an initializer.
// The compiler treats only methods starting with initWith as initializers.
-(instancetype)initWithName:(NSString *)name andAge:(int)age{
if (self = [super init]) {
self.name = name;
self.age = age;
}
return self;
}
@end
// Test
Person *p1 = [[Person alloc] init];
Person *p2 = [Person new];
Person *p3 = [[Person alloc] initWithName:@"杭城小刘2号" andAge:23];
```
![init](../assets/2017-05-23-5-56-53.png)
![init](../assets/2017-05-23-5-57-08.png)
An experiment about "custom initializers must start with initWith"
![initwith](../assets/2017-05-23-6-01-29.png)
The error message is clear: you cannot assign to self outside of an initializer.
Because the compiler considers only methods starting with initWith as initializers.

81
Chapter1 - iOS/1.3.md Normal file
View File

@@ -0,0 +1,81 @@
# loadView
1. Purpose: load the controller's view
2. When it's called: it's called the first time the controller's view is used
3. Use case: implement this method when you want to provide a custom view for the controller
Accessing the controller's view is equivalent to calling the controller's view getter:
```objective-c
-(UIView *)view
{
if(_view == nil){
[self loadView];
[self viewDidLoad];
}
return _view;
}
```
# Controller view loading flow
![Controller view loading flow](../assets/2287777-b6128646373dfffb.png)
- The controller's `init` method internally calls `initWithNibName`
`MyViewController *vc = [[MyViewController alloc] init];`
Notes:
The system's decision logic assumes: no nibName specified; no custom loadView method; the controller is named ...Controller
Decision rules:
- Check whether a nibName was specified; if specified, load that nib
- Check whether there's an xib with the same name as the controller but without "Controller" in its name; if present, load it
- If the previous step doesn't find one, check whether an xib with the same name as the controller class exists; if present, load it
- If no xib describes the controller's view, do not load any xib
## How MyViewController loads its view
- Check whether an xibName was specified; if so, load the specified xib
- Check whether there's an xib with the same name as the controller class but without "Controller" in the name
- Check whether there's an xib with the same name as the controller class; if present, load it
- Otherwise, create an empty view directly
Example
```objective-c
// in AppDelegate
ViewController *vc = [[ViewController alloc] init];
vc.view.backgroundColkor = [UIColor redColor];
self.window.rootViewController = vc;
[pself.window makeKeyAndVisable];
// ViewController
-(UIView *)view{
if(!_view){
[self loadView];
[self viewDidLoad];
}
}
-(void)loadView{
UIView*view = [[UIView alloc] initWithFrame:[UIScreen mainScreen].bounds];
view.backgroundColor = [UIColor greenColor];
self.view = view;
}
-(void)viewDidload{
[super viewDidload];
self.view.backgroundColor = [UIColor brownColor];
}
```
### What color will the interface be at this point?
Many people might answer "green." Actually, the answer is red.
Why? In AppDelegate, `vc.view.backgroundColor` calls vc's view getter. Inside the getter it checks if `_view` exists; if not, it creates a new UIView by calling `[self loadView]`. After creating the view it calls `viewDidLoad`; if the view already exists it returns it directly. So the sequence is: first green, then brown, and finally red.
#### An official explanation
![Apple documentation](../assets/2287777-8ff7c3b976ffb29a.png)

View File

@@ -119,7 +119,7 @@ Part One mainly introduces problems encountered or interesting knowledge in iOS
* [114. Swift optimizations](1.114.md)
* [115. AI empowerment on the endpoint](1.115.md)
* [116. Deep dive into Swift classes](1.116.md)
* [117. Swift protocol exploration](1.117.md]
* [117. Swift protocol exploration](1.117.md)
* [118. Swift error handling](1.118.md)
* [119. Analyze Swift String](1.119.md)
* [120. Swift access control](1.120.md)
@@ -127,7 +127,16 @@ Part One mainly introduces problems encountered or interesting knowledge in iOS
* [122. Swift literal fundamentals](1.122.md)
* [123. Swift pattern matching](1.123.md)
* [128. SwiftUI research](1.128.md)
* [129. Swift Dictionary](1.129.md)
* [130. GCD](1.130.md)
* [131. Package management tools](1.131.md)
* [132. Dynamic debugging](1.132.md)
* [133. Using PGO in the compiler to optimize app performance](1.133.md)
* [134. Removing dead code](1.134.md)
* [135. Framework design](1.135.md)
* [136. Engineering practices](1.136.md)
* [137. Quality testing](1.137.md)
* [138. AFNetworking source code walkthrough](1.138.md)
* [139. Graphics rendering techniques](1.139.md)
* [140. Aspects](1.140.md)
* [143. AI empowerment on the endpoint](1.143.md)