ForgetSou | Blog

❤ 武统台湾 刻不容缓 ❤

0%

2020-10-15 OC

一.define和const常量的区别

define 是定义宏的指令,程序在预处理阶段进行替换,在程序运行时并没有用 define 定义的宏,系统不会为其分配内存并在编译时也不会进行数据类型检查,大量使用宏会导致二进制文件变大。

const 定义的常量是在程序运行时存放在常量表中,系统为其分配内存并在编译时进行数据类型检查。

define 不能调试,const可以调试;

define 可以定义简单函数,const只能定义常量

// 宏
#define HSCoder @"你好“
// 变量
NSString *coder = @"你好";
// 全局变量
extern NSString *coder;
// 全局常量
extern NSString *const coder;
// 全局指针变量
extern const NSString *coder;
extern NSString const *coder;
// 局部常量
static NSString *const coder = @"你好";
// 常量
const NSString *coder;// *corder不能被修改 corder可以被修改
NSString const *coder;// *corder不能被修改 corder可以被修改
NSString *const coder;// *corder可以被修改 corder不能被修改
// const右边的不能被修改
// 当我们定义一个常量且不想被修改应该使用 NSString *const coder;

二.结构体( struct )和类( class )的区别

struct 和 class都可以将多个数据封装为一个整体

// 结构体(struct)
struct People {
NSString *name;
int age;
CGFloat height;
};
// 类(class)
@interface People : NSObject {
NSString *name;
int age;
CGFloat height;
}
@end
  • struct 只能封装数据,class可以封装行为
  • struct 变量分配在栈空间(如果是一个局部变量的情况下),class对象分配在堆空间。
  • 赋值 :结构体是(拷贝),对象之间是(地址)
  • 如果待封装的数据有属性也有方法,只能使用class
  • 如果属性较少,使用struct(分配在栈,提高运行效率);属性较多时使用class

三.@synthesize和@dynamic的区别

@dynamic 需要自己实现 setter getter方法

@synthesize 系统会自动生成 setter getter方法,默认定义一个属性时,系统会自动生成,不需要自己手动写,自己手动添加 setter 或 getter方法后会覆盖系统默认的 setter 和 getter 方法。

四.@property的本质

@property = ivar(实例变量) + setter + getter

property(属性)的主要作用是封装对象的属性,对象通常会把需要的数据保存为各种ivar(实例变量),实例变量一般通过存取方法来访问ivar。

#import <Foundation/Foundation.h>

@interface PZMan : NSObject

@property (strong, nonatomic) NSString *subName;

@end

#import "PZMan.h"

@implementation PZMan
@synthesize subName = _subName;

/// setter方法
- (void)setSubName:(NSString *)subName {
_subName = subName;
}

/// getter方法
- (NSString *)subName {
if (_subName.length > 0) {
return @"PZ";
} else {
return _subName;
}
}
@end

五.Mac下终端升级(iTem2 + oh-my-zsh + powerlevel10k)

https://blog.csdn.net/weixin_43269020/article/details/105853693

六.iOS14 适配

  1. UIDatePicker

    Xcode12 UIDatePicker 需要在设置frame之前添加preferredDatePickerStyle

    typedef NS_ENUM(NSInteger, UIDatePickerStyle) {
    /// Automatically pick the best style available for the current platform & mode.
    UIDatePickerStyleAutomatic,
    /// Use the wheels (UIPickerView) style. Editing occurs inline.
    UIDatePickerStyleWheels,
    /// Use a compact style for the date picker. Editing occurs in an overlay.
    UIDatePickerStyleCompact,
    /// Use a style for the date picker that allows editing in place.
    UIDatePickerStyleInline API_AVAILABLE(ios(14.0)) API_UNAVAILABLE(tvos, watchos),
    } API_AVAILABLE(ios(13.4)) API_UNAVAILABLE(tvos, watchos);

    /// Request a style for the date picker. If the style changed, then the date picker may need to be resized and will generate a layout pass to display correctly.
    @property (nonatomic, readwrite, assign) UIDatePickerStyle preferredDatePickerStyle API_AVAILABLE(ios(13.4)) API_UNAVAILABLE(tvos, watchos);

    示例

    UIDatePicker *picker = [[UIDatePicker alloc] init];
    picker.datePickerMode = UIDatePickerModeDateAndTime;
    if (@available(iOS 13.4, *)) {
    picker.preferredDatePickerStyle = UIDatePickerStyleAutomatic;
    } else {
    // Fallback on earlier versions
    }
    picker.frame = CGRectMake(0, 0, self.view.frame.size.width, 200);
    [self.view addSubview:picker];
  2. 复制黏贴

    弹出提示的原因是使用 UIPasteboard 访问用户数据,访问以下数据都会弹出 toast 提示。

    @property(nullable,nonatomic,copy) NSString *string API_UNAVAILABLE(tvos) API_UNAVAILABLE(watchos);
    @property(nullable,nonatomic,copy) NSArray<NSString *> *strings API_UNAVAILABLE(tvos) API_UNAVAILABLE(watchos);

    @property(nullable,nonatomic,copy) NSURL *URL API_UNAVAILABLE(tvos) API_UNAVAILABLE(watchos);
    @property(nullable,nonatomic,copy) NSArray<NSURL *> *URLs API_UNAVAILABLE(tvos) API_UNAVAILABLE(watchos);

    @property(nullable,nonatomic,copy) UIImage *image API_UNAVAILABLE(tvos) API_UNAVAILABLE(watchos);
    @property(nullable,nonatomic,copy) NSArray<UIImage *> *images API_UNAVAILABLE(tvos) API_UNAVAILABLE(watchos);

    @property(nullable,nonatomic,copy) UIColor *color API_UNAVAILABLE(tvos) API_UNAVAILABLE(watchos);
    @property(nullable,nonatomic,copy) NSArray<UIColor *> *colors API_UNAVAILABLE(tvos) API_UNAVAILABLE(watchos);

    iOS14 新增了两个 API 可以用于规避该提示。

    /// NSString value, suitable for implementing "Paste and Go"
    UIKIT_EXTERN UIPasteboardDetectionPattern const UIPasteboardDetectionPatternProbableWebURL API_AVAILABLE(ios(14.0));

    /// NSString value, suitable for implementing "Paste and Search"
    UIKIT_EXTERN UIPasteboardDetectionPattern const UIPasteboardDetectionPatternProbableWebSearch API_AVAILABLE(ios(14.0));
    // 可用于规避提示,但只能用于判断剪切板中是否有 URL,并不是真正的访问剪贴板数据,也拿不到剪切板的真实数据。
    // Detection

    /// Detects patterns in the first pasteboard item.
    ///
    /// @param patterns Detect only these patterns.
    /// @param completionHandler Receives which patterns were detected, or an error.
    - (void)detectPatternsForPatterns:(NSSet<UIPasteboardDetectionPattern> *)patterns
    completionHandler:(void(^)(NSSet<UIPasteboardDetectionPattern> * _Nullable,
    NSError * _Nullable))completionHandler NS_REFINED_FOR_SWIFT API_AVAILABLE(ios(14.0));

    /// 可用于规避提示,但只能用于判断剪切板中是否有 URL,并不是真正的访问剪贴板数据,也拿不到剪切板的真实数据。
    /// Detects patterns in the specified pasteboard items.
    ///
    /// @param patterns Detect only these patterns.
    /// @param itemSet Specifies which pasteboard items by their position. Nil means all items.
    /// @param completionHandler Receives which patterns were detected per item specified,
    /// or an error.
    - (void)detectPatternsForPatterns:(NSSet<UIPasteboardDetectionPattern> *)patterns
    inItemSet:(NSIndexSet * _Nullable)itemSet
    completionHandler:(void(^)(NSArray<NSSet<UIPasteboardDetectionPattern> *> * _Nullable,
    NSError * _Nullable))completionHandler NS_REFINED_FOR_SWIFT API_AVAILABLE(ios(14.0));


    /// 可以获得具体的 URL 信息,但是会触发剪切板提示。并且实测当用户剪切板中包含多个 URL 时只会返回第一个。
    /// Detects patterns and corresponding values in the first pasteboard item.
    ///
    /// @param patterns Detect only these patterns.
    /// @param completionHandler Receives which patterns and values were detected, or an error.
    - (void)detectValuesForPatterns:(NSSet<UIPasteboardDetectionPattern> *)patterns
    completionHandler:(void(^)(NSDictionary<UIPasteboardDetectionPattern, id> * _Nullable,
    NSError * _Nullable))completionHandler NS_REFINED_FOR_SWIFT API_AVAILABLE(ios(14.0));

    /// 可以获得具体的 URL 信息,但是会触发剪切板提示。并且实测当用户剪切板中包含多个 URL 时只会返回第一个。
    /// Detects patterns and corresponding values in the specified pasteboard items.
    ///
    /// @param patterns Detect only these patterns.
    /// @param itemSet Specifies which pasteboard items by their position. Nil means all items.
    /// @param completionHandler Receives which patterns and values were detected per item specified,
    /// or an error.
    - (void)detectValuesForPatterns:(NSSet<UIPasteboardDetectionPattern> *)patterns
    inItemSet:(NSIndexSet * _Nullable)itemSet
    completionHandler:(void(^)(NSArray<NSDictionary<UIPasteboardDetectionPattern, id> *> * _Nullable,
    NSError * _Nullable))completionHandler NS_REFINED_FOR_SWIFT API_AVAILABLE(ios(14.0));

    使用示例

    // 剪切板
    UIPasteboard *board = [UIPasteboard generalPasteboard];
    if (@available(iOS 14.0, *)) {
    NSSet *patterns = [NSSet setWithObjects:UIPasteboardDetectionPatternProbableWebURL, UIPasteboardDetectionPatternNumber, UIPasteboardDetectionPatternProbableWebSearch, nil];
    [board detectPatternsForPatterns:patterns
    completionHandler:^(NSSet<UIPasteboardDetectionPattern> * _Nullable set, NSError * _Nullable error) {
    BOOL hasNumber = NO, hasURL = NO, hasSearch = NO;
    for (NSString *type in set) {
    if ([type isEqualToString:UIPasteboardDetectionPatternProbableWebURL]) {
    hasURL = YES;
    } else if ([type isEqualToString:UIPasteboardDetectionPatternNumber]) {
    hasNumber = YES;
    } else if ([type isEqualToString:UIPasteboardDetectionPatternProbableWebSearch]) {
    hasSearch = YES;
    }
    }
    if (hasSearch) {

    }
    if (hasURL) {

    }
    if (hasNumber) {

    }
    }];
    }
    // 不能使用.string或.strings否则还是会弹出提示框
    NSString *pastString = board.string;
    NSLog(@"pastString = %@", pastString);
  3. KVC(UIPageControl的pageimage)

    ​ 私有方法 KVC 不允许使用,日志报 'setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key _pageImage.'
    ​ 在iOS14下设置UIPageControlpageimage,会导致奔溃,不能再用了。

    if (@available(iOS 14.0,*)) {
    pageControl.preferredIndicatorImage = [self imageWithColor:[UIColor whiteColor]];
    pageControl.currentPageIndicatorTintColor = [UIColor redColor];
    pageControl.pageIndicatorTintColor = [UIColor blueColor];
    }else{
    [pageControl setValue:[UIImage imageNamed:@"pageContrImg"]forKeyPath:@"pageImage"];
    [pageControl setValue:[UIImage imageNamed:@"pageContrCurrentImg"]forKeyPath:@"currentPageImage"];
    }
  4. TableViewCell

    ​ xcode12上cell添加button,不能[self addSubview:self.cellBtn] 需要[self.contentView addSubview:self.cellBtn]contentView的层级被提上来了,self addSubview会导致button不响应点击事件.也可以在添加控件之前提前调用contentView

  5. 相机权限

    ​ iOS14 新增了Limited Photo Library Access 模式,在授权弹窗中增加了 Select Photo 选项。用户可以在 App 请求调用相册时选择部分照片让 App 读取。从 App 的视⻆来看,你的相册里就只有这几张照片,App 无法得知其它照片的存在。

    PHAuthorizationStatusLimited 时,如果未进行适配,有可能会在每次触发相册功能时都进行弹窗询问用户是否需要修改照片权限。

    ​ 对于这种情况可通过在 Info.plist 中设置PHPhotoLibraryPreventAutomaticLimitedAccessAlert的值为YES来阻止该弹窗反复弹出,并且可通过下面这个 API 来主动控制何时弹出PHPickerViewController进行照片选择。

    ​ 具体可以参考文章iOS14 隐私适配及部分解决方案

-------------本文结束感谢您的阅读-------------
坚持原创技术分享,您的支持将鼓励我继续创作!

欢迎关注我的其它发布渠道