swift入门_属性的那些坑

说起swift的第一个难点,就是关于属性.对于刚开始接触OC时实例变量/成员变量/属性,傻傻分不清.自从接触到了Swift,才知道那都不是事儿.
下面就来看看Swift的属性是怎么回事.
属性又分为存储属性,计算属性,类属性

1.存储属性

对于存储属性,没有什么好说的.对于熟悉OC的来说是一样的.

// 定义一个类
class Person {
  // 下面的定义的都是属性,而且是存储属性,和OC相同,为了保存属性值
  // 使用var 定义可变属性变量
    var age: Int = 10
  // 使用let 定义不可变的属性常量
    let name: String = "张三"
  // 使用? 表示这个是可选值
 // 上面两个变量必须有初始值,所以在定义变量时进行了赋值
 // height变量由于是可选的,没有必要赋初值
    var height: Double?
}
// 这里定义了一个Person对象
let p = Person()
// 由于age,height都是变量,可以直接通过点语法进项属性赋值
p.age = 5 
p.height = 200
//p.name = "李四" // 由于name是定义的是常量,这里赋值是报错的

2.计算属性

刚才提到的存储属性还是觉得很正常的,但是用习惯了OC,对于习惯了set和get方法的人们来说,刚开始简直是噩梦.这玩意是什么鬼.
下面拿来我之前写过的一个分类来说明一下.
有时候我们为了设置frame的x,y,w,h我们需要一层层点下去,这里写一个分类,为了方便赋值取值.我们直接为View加了个属性.这样子我们通过set和get进行赋值和取值.这个应该很熟悉了

@property (nonatomic, assign) CGFloat x;
@property (nonatomic, assign) CGFloat y;
@property (nonatomic, assign) CGFloat width;
@property (nonatomic, assign) CGFloat height;

// x
- (void)setX:(CGFloat)x {
    CGRect frame = self.frame;
    frame.origin.x = x;
    self.frame = frame;
}

- (CGFloat)x {
    return self.frame.origin.x;
}

//...写法类似,只去了个

那个类似的功能我们使用swift来看一下,对UIView写了一个扩展.

extension UIView {
    var x: CGFloat {
    // get方法
    // 需要注意的是:写了set,get是必须写的,如果只写get,相当于只读.
        get {
           return self.frame.origin.x
        }
        // set 方法
        set {
            var frame = self.frame
            frame.origin.x = newValue
            self.frame = frame
        }
    }
}

看到Swift的代码,可能会很吃惊,这不是很像吗?对是相同的代码.写法是相同的.但是实际上和OC还是有很大区别的.
注意
1.计算属性的值是不固定的,是计算得来的,所以只能使用var来修饰,不能使用let
2.计算属性本身是不能直接复制的,他是通过其他的变/常量计算结果得到的数据.

// 由于Swift我们没有成员变量,所以我们要避免死循环的问题
// 所以再OC中常用到的_xxx,在Swift中不好用了

class Person {
// 下面由于进行了赋值,其实是一个存储属性,再去写get方法是没意义的.
//    var age: Int = 10 {
//        return 20
//    }
    
  // 这种情况都会是死循环,具体是什么原因,熟悉OC的应该没问题吧
    var age: Int {
        get {
            return age
        }
        
        set {
            age = newValue
        }
    }
}

说道这里我们就得提一下懒加载,在OC中我们的懒加载其实是重写了属性的get方法,在Swift中就要改变一下写法了

// 定义了一个属性
@property (nonatomic, strong) NSMutableArray *topics;

// 懒加载
- (NSMutableArray *)topics
{
    if (!_topics) {
        _topics = [NSMutableArray array];
    }
    return _topics;
}

Swift中的懒加载会使用到关键字lazy

lazy var topics: NSMutableArray? = NSMutableArray()

// 当然如果要在懒加载时做一下初始化配置,那么我们会使用闭包的形式
lazy var topics: NSMutableArray? = {
    // 这里面进行初始化配置
}()

 // 懒加载 ps: 这是从项目中截取的一段,为了说明问题,直接拷贝会报错
    lazy var pictureView: DZTopicPictureView? = {
        let pictureView = DZTopicPictureView.pictureView()
        self.contentView.addSubview(pictureView)
        return pictureView 
    }()

通过这里我们似乎觉的get/set和OC中有了区别了,那么再看看下面一个

3.属性监视器

所谓的属性监视器,就是在属性值的改变前后进行一些操作,这个才是相当于我们的OC中所说的get方法,拿到值后再进行一些操作

class Person {
    var age: Int?  {
        willSet {
            print(newValue) // newValue将要新赋的值5
        }
  // 当然如果觉得不习惯使用newValue/oldValue, 我们可以取一个内部变量名,didSet也是可以的
 //  willSet(age) {
 //           print(age)            
  //      }
        didSet {
            print(oldValue) // oldValue表示旧值 nil
        }
    }    
}

let p = Person()
p.age = 5

注意
1.计算属性有get和set方法去改变属性值,因此监听就就没什么意义了
2.设置默认值时不会调用willSet和didSet,见下面代码.

class Person {
  // 默认值
    var age: Int? = 20  {
        willSet {
            print(newValue) 
        }
        didSet {
            print(oldValue)
        }
    }    
}

3.willSet和didSet set和get 是不能共存的.

所以说在定义属性前还是要想好属性是做什么用的

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

推荐阅读更多精彩内容