当我们写一个功能时,有一点思路,但又不太确定。怎么办呢?我们可在github上找一些
star
比较多的开源项目,看他们的处理方式如何。
- 判断当前设备是否是
iphonex
,iphoneXs
、iPhone XS Max
、iPhone XR
。在TZImagePickerController 中
+ (BOOL)tz_isIPhoneX {
return (CGSizeEqualToSize([UIScreen mainScreen].bounds.size, CGSizeMake(375, 812)) ||
CGSizeEqualToSize([UIScreen mainScreen].bounds.size, CGSizeMake(812, 375)) ||
CGSizeEqualToSize([UIScreen mainScreen].bounds.size, CGSizeMake(414, 896)) ||
CGSizeEqualToSize([UIScreen mainScreen].bounds.size, CGSizeMake(896, 414)));
}
+ (CGFloat)tz_statusBarHeight {
return [self tz_isIPhoneX] ? 44 : 20;
}
- 拍照时,检测相机权限。在
TZImagePickerController
中,提示部分可自定义。
/// 拍照按钮点击事件
- (void)takePhoto {
AVAuthorizationStatus authStatus = [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeVideo];
if ((authStatus == AVAuthorizationStatusRestricted || authStatus ==AVAuthorizationStatusDenied)) {
// 无权限 做一个友好的提示
} else if (authStatus == AVAuthorizationStatusNotDetermined) {
// 防止用户首次拍照拒绝授权时相机页黑屏
[AVCaptureDevice requestAccessForMediaType:AVMediaTypeVideo completionHandler:^(BOOL granted) {
if (granted) {
dispatch_async(dispatch_get_main_queue(), ^{
// 有权限 做下一步操作
});
}
}];
} else {
// 有权限 做下一步操作
}
}
- 检测相册权限。在
TZImageManager
中,若返回NO
,可做相应提示。
/// Return YES if Authorized 返回YES如果得到了授权
- (BOOL)authorizationStatusAuthorized {
NSInteger status = [PHPhotoLibrary authorizationStatus];
if (status == 0) {
/**
* 当某些情况下AuthorizationStatus == AuthorizationStatusNotDetermined时,无法弹出系统首次使用的授权alertView,系统应用设置里亦没有相册的设置,此时将无法使用,故作以下操作,弹出系统首次使用的授权alertView
*/
[self requestAuthorizationWithCompletion:nil];
}
return status == 3;
}
- (void)requestAuthorizationWithCompletion:(void (^)(void))completion {
void (^callCompletionBlock)(void) = ^(){
dispatch_async(dispatch_get_main_queue(), ^{
if (completion) {
completion();
}
});
};
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
[PHPhotoLibrary requestAuthorization:^(PHAuthorizationStatus status) {
callCompletionBlock();
}];
});
}
- 书写单例,在
AFNetworking
中
+ (instancetype)sharedManager {
static AFNetworkActivityIndicatorManager *_sharedManager = nil;
static dispatch_once_t oncePredicate;
dispatch_once(&oncePredicate, ^{
_sharedManager = [[self alloc] init];// 调用init 方法
});
return _sharedManager;
}
- (instancetype)init {
self = [super init];
if (!self) {
return nil;
}
return self;
}
-
weakSelf
和strongSelf
定义和用法,在YYKit
中
__weak __typeof__ (self) _self = self;
if (_taskID == UIBackgroundTaskInvalid) {
_taskID = [[UIApplication sharedExtensionApplication] beginBackgroundTaskWithExpirationHandler:^{
__strong __typeof (_self) self = _self;
if (self) {
[self cancel];
self.finished = YES;
}
}];
}
也可以使用在YYKitMacro.h
中定义的宏,通过@weakify(self)
和@strongify(self)
调用,后面不用加标点符号。
#ifndef weakify
#if DEBUG
#if __has_feature(objc_arc)
#define weakify(object) autoreleasepool{} __weak __typeof__(object) weak##_##object = object;
#else
#define weakify(object) autoreleasepool{} __block __typeof__(object) block##_##object = object;
#endif
#else
#if __has_feature(objc_arc)
#define weakify(object) try{} @finally{} {} __weak __typeof__(object) weak##_##object = object;
#else
#define weakify(object) try{} @finally{} {} __block __typeof__(object) block##_##object = object;
#endif
#endif
#endif
#ifndef strongify
#if DEBUG
#if __has_feature(objc_arc)
#define strongify(object) autoreleasepool{} __typeof__(object) object = weak##_##object;
#else
#define strongify(object) autoreleasepool{} __typeof__(object) object = block##_##object;
#endif
#else
#if __has_feature(objc_arc)
#define strongify(object) try{} @finally{} __typeof__(object) object = weak##_##object;
#else
#define strongify(object) try{} @finally{} __typeof__(object) object = block##_##object;
#endif
#endif
#endif
- 开发环境需要打印日志,生产环境不需要。
MJRefresh
中
// 日志输出
#ifdef DEBUG
#define MJRefreshLog(...) NSLog(__VA_ARGS__)
#else
#define MJRefreshLog(...)
#endif
- 断言
NSAssert
和NSParameterAssert
NSAssert和NSParameterAssert在开发环境中经常被使用,调试和验证代码参数的完整性,断言为真,则表明程序运行正常,而断言为假,则意味着它已经在代码中发现了意料之外的错误💥。xCode中的断言在Debug模式默认是开启的,Realse版本中是禁用的.
网友评论