学计算机的那个

不是我觉到、悟到,你给不了我,给了也拿不住;只有我觉到、悟到,才有可能做到,能做到的才是我的.

0%

iOS特殊技巧

艾德的父亲给所有逍遥法外的罪犯起了一个统一的代称-罗罗·汤马西.——–<洛城机密>

这篇博客总结一些,iOS开发中遇到的,比较特殊的问题,或者暂时想不到解决办法的问题。有些问题是个人能力不足,暂时没找到解决方案,有些可能就是苹果系统本身的问题。

特殊情况

需要手动添加@synthesize的情况

  • 你手动同时重写 setXXX 和 XXX(get) 方法, 就不会为你自动生成 _xxx 实例变量
1
2
3
4
@interface Cat : NSObject
@property (copy, nonatomic) NSString *name;
- (void)echo;
@end

解决

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#import "Cat.h"
@implementation Cat

@synthesize name = _name;

- (void)echo
{
_name = @"XiaoHua";
NSLog(@"name = %@", _name);
}
- (void)setName:(NSString *)name
{
//TODO
}
- (NSString *)name
{
return _name;
}
@end

单例的创建与释放

  • 线程安全的单例创建
1
2
3
4
5
6
7
8
+ (instancetype)shareSingleton {
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        singleton = [[self alloc]init];
    });
    return singleton;
}

  • 单例的销毁
  1. 必须把static dispatch_once_t onceToken; 这个拿到函数体外,成为全局的.
  2. onceToken=0;
1
2
3
4
5
6
+(void)attempDealloc{
    onceToken = 0// 只有置成0,GCD才会认为它从未执行过.它默认为0.这样
    才能保证下次再次调用shareInstance的时候,再次创建对象.
    [_instance release];
    _instance = nil;
 }
  • onceToken说明
1
2
3
4
GCD创建:dispatch_once中dispatch_once_t类型为typedef long

•onceToken= 0,线程执行dispatch_once的block中代码

•onceToken= -1,线程跳过dispatch_once的block中代码不执行

•onceToken= 其他值,线程被线程被阻塞,等待onceToken值改变

iOS定时器时间准么?

对于NSTimer是否时间准确呢?大家可能都知道是时间不准确的,因为受RunLoop的影响,那么GCD中也有延时,如果用GCD来做延时,那时间准确吗?

答案是GCD的time是准确的,GCD 的线程管理是通过系统来直接管理的。GCD Timer 是通过 dispatch port 给 RunLoop 发送消息,来使 RunLoop 执行相应的 block,如果所在线程没有 RunLoop,那么 GCD 会临时创建一个线程去执行 block,执行完之后再销毁掉,因此 GCD 的 Timer 是不依赖 RunLoop 的。

iOS中纯代码创建的UI控件使用weak还是strong?

当addSubview:时,该UI控件已经被VC的view持有了。如果VC把该控件声明成了strong,就会同时有两个对象持有这个UI控件,一个是VC,一个是VC的view,所以只有这两个持有者都释放了才会释放该UI控件。声明成weak的好处是不会干扰该UI控件的正常的生命周期

使用weak连接控件,只要我们在创建控件的时候,在当前的作用域 { xxx }中,添加到contentView上,就能为其添加强引用保证它不被销毁。然后当我们removeFromSuperView的时候,可以实现控件的销毁

罗罗·汤马西

iOS原生二维码,条形码识别问题

  • AVFoundation使用多译码器扫描的时候。不管有没有设置扫描区域(setRectOfInterest:),二维码可以在扫描区域的任意位置响应扫描成功,但是条形码却不行,只能在扫码区域的中间位置响应。
1
2
3
4
5
6
7
8
9
10
官网文档解释如下

按照ISO标准解碼,实际上是,按照1:1:3:1:1去寻找那三个寻像图形,就是标志性的
大方块。然后圈出二维码大小再去解碼的。也就是说,再没设定边界的情况下全屏都可
以。

而条形码完全不同,他是在Detect Center那个点,画一个无限延伸的米字型,然后
去判断每一条在线能否解析出条形码所需要的0101010序列。而iOS默认的Center是
Layer 的 Center。所以条形码扫描仪上往往会有一条红线,这并不是为了拟物化,
而是告诉用户一定要用这条线对准条形码,否则会有扫不上的可能性
  • 有时候会遇到,当AVFoundation使用多译码器扫描的时候。二维码是秒杀,但是条形码却经常扫不上。如果去掉二维码的话,条形码扫描又秒杀的问题。如果是二维码和条形码一起,条形码扫描中心线就只有center。但是如果只有条形码,扫描中心线是center+additional。additional的存在的意义是用更加优秀且稍微耗时的算法去优化扫描精准度,也就是牺牲效率换精确度。

进入后台播放音频文件时提示错误

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
- (void)applicationWillResignActive:(UIApplication *)application {
[[UIApplication sharedApplication] beginReceivingRemoteControlEvents];
AVAudioSession* session=[AVAudioSession sharedInstance];
[session setActive:YES error:nil];
[session setCategory:AVAudioSessionCategoryPlayback error:nil];
}

- (void)beginTask
{
bgTaskIdentifier= [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^{
//如果在系统规定时间3分钟内任务还没有完成,在时间到之前会调用到这个方法
[self endBack];
}];
}
//结束后台运行,让app挂起
- (void)endBack
{
//切记endBackgroundTask要和beginBackgroundTaskWithExpirationHandler成对出现
[[UIApplication sharedApplication] endBackgroundTask:bgTaskIdentifier];
bgTaskIdentifier = UIBackgroundTaskInvalid;
}

- (void)applicationDidEnterBackground:(UIApplication *)application {
[self beginTask];
}
1
2
Can't end BackgroundTask: no background task exists with identifier 2 (0x2), or it may have already been 
ended. Break in UIApplicationEndBackgroundTaskError() to debug.

遇到这种问题,当时是一脸懵逼的,除了谷歌之外,一点思路都没有,在我契而不舍的搜索之下,结果发现stackoverflow上有人提出这是iOS13特有的系统Bug。然后我拿模拟器iOS12的系统测试,还真是没有报错….

新机第一次安装、第一次启动的时候,app没数据。kill掉重新打开就好了

开发App的时候,有个别用户反应,第一次安装,第一次启动App的时候,用户隐私页面是空白的,而且会一直卡在那里,退出App,再重新进入就可以了。刚开始还以为是用户的网络故障,让她切换wifi试试,然后她说又好了,所以当时也没在意,后来自己一不小心复现了。。。。

症状: iOS 10之后 国行手机

原因:

2015年底工信部起草的一份《移动智能终端应用软件(APP)预置和分发管理暂行规定》有关,规定中要求设备生产企业「未经明示且经用户同意,不得实施擅自收集使用用户个人信息、强制开启应用软件……等侵害用户合法权益和危害网络安全的行为」

在 iOS 10 中,苹果为国行 iPhone 制定了一个「联网权限」功能,「允许 XXX 使用数据?」
只有当你选择「允许」后,应用才能够开始联网。如果你没有允许,那么这个 App 将无法做任何与联网相关的动作,不管是在前台还是后台。

解决:加一个重新加载的按钮呗!

参考

  1. iOS 10 的坑:新机首次安装 app,请求网络权限“是否允许使用数据”