杂七杂八的小tips(持续更新)

一、关于NSNull

先说说nil和NULL代表的是内存中的一块空地址,NSNull表示的是一个对象,指向一个nil地址。
文档上这样描述,NSNull一个单例,NSNull是一个用来表示不允许空值集合对象中的空值的。
其实NSNull存在的意义在于,OC中集合类型只能存储对象不能存储nil。存储nil会报NSInvalidArgumentException。可以用NSNull替代。

二、self和super

在方法调用方面self表示调用自己的方法,super表示调用父类方法。
self其实是类或者对象,super是预编译指令。
super调用的方法会转换成如下指令:

//以class方法为例
[super class]
//runtime层
struct objc_super1 {
        __unsafe_unretained id receiver;
        Class superClass;
 };
struct objc_super1 obj_super = {self,class_getSuperclass(object_getClass(self))};
id obj3 = objc_msgSendSuper(&obj_super,@selector(class));

可以看出super调用方法的时候会传入当前对象

三、保证属性读写线程安全的方案

  • 方案一:读写时加锁可以实现需求,但这样所有的属性读写都是原子的,我们的需求是针对同一属性线程安全,所以这样做效率较低。
  • 方案二:可以创建一个串行队列,把读写操作放到这个串行队中同步执行,串行队列的性质可保证线程安全。优化的话,可以将写操作改为异步执行,读操作改为同步执行。这样做的好处在于写操作速度加快,不会阻塞主线程,但是究其根本所有的读写任务还是同步的,所以读写效率并不高。代码如下:
- (void)setSomeString:(NSString *)someString{
    dispatch_async(self.serialQueue, ^{
        _someString = someString;
    });
}
- (NSString *)someString{
    __block NSString * localString;
    dispatch_sync(self.serialQueue, ^{
        localString = _someString;
    })
    return localString;
}
  • 方案三:前面提到,读取操作我们可以并行去做,因为每个属性互不干扰,只要不与读取操作同事执行就可以,栅栏方法dispatch_barrier_async会在队列中必须单独执行,一定不会与其他任务并发,利用这个特性,我可以更好的实现需求。代码如下:
- (void)setSomeString:(NSString *)someString{
    dispatch_barrier_async(self.syncQueue, ^{
        _someString = someString;
    })
}
- (NSString *)someString{
    __block NSString * localString;
    dispatch_sync(self.syncQueue, ^{
        localString = _someString;
    })
    return localString;
}

以上代码在不同线程读取属性的时候,可以并发读取。同时又保证了读取时的同步。

  • 扩展,我们思考一下为什么不建议属性用atomic关键字,大家都知道,其实atomic就是通过自旋锁来保证读写线程安全的,这样同一对象所有的属性读取都是同步的,而且会阻塞主线程,所以如果必须保证属性的线程安全的话,推荐方案三。那么引申出来,如何保证两类操作之间的线程安全呢?方案三是最好的选择。

四、GCD与NSOperation

GCD是纯C的API,而NSOperation是面向对象的,GCD是用块这种轻量级的数据结构来表示任务的,而GCD则是用更加重量级的对象来表示的,NSOperation是基于GCD的那NSOperation的好处如下。

  • NSOperation可以通过cancel方法轻易的取消队列中的任务,而GCD把块安排到队列中后是无法取消的。
  • GCD可以轻易的设置依赖关系,比如一个网络操作需要之前的5个任务处理完毕之后才能进行,我们可以将请求任务依赖于那五个任务,这样简单的可以实现需求,用GCD我们要用dispatch_group或者信号量的同步方式。
  • 通过键值观察可以了解到NSOperation的声明周期,比如属性isCancel、isFinished等等。NSOperation适合进行比GCD更加精密的操作。
  • NSOperation可以执行操作的优先级,队列中优先级高的任务先执行,GCD则没有直接操作优先级的功能,只能操作队列的优先级。
  • NSOperation对象内置了很多方便的子类,比如NSBlockOperation。

五、用NSCache的几点好处

  • 低内存时自动删减缓存,LRU(最近最少使用)缓存淘汰。
  • 不同于NSDictionary,NSCache并不会拷贝键,而是会保留键,一些不支持拷贝的类也可以作为键。
  • 可以设置最大开销,和数量,但这并不是对cache的硬限制,只做参考。
  • NSCache可以配合NSPurgeableData使用,当NSPurgeableData对象被系统释放的时候,缓存自动清除。

六、bounds和frame的区别?

  • bounds:相对自身来说的,控件的内部尺寸,如果修改了Bounds,子控件的相对位置也会发生改变。
  • Frame:相对于父控件来说的,是控件的外部尺寸。
    举个例子:
        let view = UIView(frame: CGRect.init(x: 100, y: 100, width: 100, height: 100));
        view.backgroundColor = UIColor.red;
        self.view.addSubview(view);
        
        let subView = UIView(frame: CGRect.init(x: 20, y: 20, width: 60, height: 60));
        subView.backgroundColor = UIColor.blue;
        view.addSubview(subView);
        
        print("viewFrame:\(view.frame) viewBounds:\(view.bounds)  subViewFrame:\(subView.frame)");
        
        view.transform = CGAffineTransform.init(scaleX: 2, y: 2);
        
        print("viewFrame:\(view.frame) viewBounds:\(view.bounds)  subViewFrame:\(subView.frame)");

//打印结果:
viewFrame:(100.0, 100.0, 100.0, 100.0) viewBounds:(0.0, 0.0, 100.0, 100.0)  subViewFrame:(20.0, 20.0, 60.0, 60.0)
viewFrame:(50.0, 50.0, 200.0, 200.0) viewBounds:(0.0, 0.0, 100.0, 100.0)  subViewFrame:(20.0, 20.0, 60.0, 60.0)

如上代码给一个视图放大而被,发现其frame改变了,因为锚点默认是中心,所以按中心放大,但是其bounds没有改变,subView的frame也没有改变。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,029评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,395评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,570评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,535评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,650评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,850评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,006评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,747评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,207评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,536评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,683评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,342评论 4 330
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,964评论 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,772评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,004评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,401评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,566评论 2 349

推荐阅读更多精彩内容

  • Swift1> Swift和OC的区别1.1> Swift没有地址/指针的概念1.2> 泛型1.3> 类型严谨 对...
    cosWriter阅读 11,092评论 1 32
  • 1.设计模式是什么? 你知道哪些设计模式,并简要叙述?设计模式是一种编码经验,就是用比较成熟的逻辑去处理某一种类型...
    龍飝阅读 2,140评论 0 12
  • 最全的iOS面试题及答案 iOS面试小贴士 ———————————————回答好下面的足够了-----------...
    zweic阅读 2,695评论 0 73
  • 【结论论点】 作者认为反思可以促进已有知识产生新知识 【思考】 那我们如何去做到这一点呢? 作者又是如何看待“反思...
    快乐的阿紫阅读 235评论 0 3
  • 作者原创,转载请联系作者经过建立Netconnection和CreateStream之后,客户端就可以进行相应的流...
    Alfie20阅读 3,329评论 0 1