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

2019-06-19  本文已影响0人  我是繁星

一、关于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;
}
- (void)setSomeString:(NSString *)someString{
    dispatch_barrier_async(self.syncQueue, ^{
        _someString = someString;
    })
}
- (NSString *)someString{
    __block NSString * localString;
    dispatch_sync(self.syncQueue, ^{
        localString = _someString;
    })
    return localString;
}

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

四、GCD与NSOperation

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

五、用NSCache的几点好处

六、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也没有改变。

上一篇 下一篇

猜你喜欢

热点阅读