2016-09-16 20:48:18 github_26672553 阅读数 4253

Swift中类的属性有多种
存储属性:存储实例的常量和变量
计算属性:通过某种方式计算出来的属性
类属性:与整个类自身相关的属性

一、存储属性

存储属性是最简单的属性,它作为类实例的一部分,用于存储常量和变量;
可以给存储属性提供一个默认值,也可以在初始化中个对其进行初始化。
下面是存储属性的写法:

//: Playground - noun: a place where people can play

import UIKit

class Student : NSObject {
    // 定义存储属性
    var age : Int = 0
    var name : String?  // “?”符号,表示name为可选类型,初始化值为nil
}

// 实例化类
let stu = Student()
// 给属性赋值
stu.age = 10
stu.name = "jack"

// 获取属性值
print(stu.age)  // 10

// 因为name是可选类型,可以进行解包 stu.name!
// 但解包是一个危险的操作,所以一般采用可选绑定的方式
if let name = stu.name {
    print(name)
}

二、计算属性

再定义2个属性:

    // 数学成绩
    var mathScore : Double = 0.0
    // 语文成绩
    var chineseScore : Double = 0.0

给这个2个属性赋值并计算平均成绩:

stu.mathScore = 78
stu.chineseScore = 88.88

// 计算平均成绩
let avgScore = (stu.mathScore + stu.chineseScore) * 0.5
print(avgScore)

那么问题来了:如果这个平均成绩我们在很多地方都要用到,每次都像上面这样写就未免太low了吧?

1.诶,可以写个方法专门获取平均成绩啊:

    // 定义一个方法,返回平均成绩
    func getAvgScore() -> Double {
        return (mathScore + chineseScore) * 0.5
    }

调用该方法:

print(stu.getAvgScore())

2.难道Swift就没有什么高大上的方式么?

    // 定义计算属性:通过别的方式计算到结果的属性称之为计算属性
    var avgScore : Double {
        return (mathScore + chineseScore) * 0.5
    }

然后访问这个属性就拿到平均成绩了:

print(stu.avgScore)

三、类属性

定义:

    // 定义类属性
    static var courseCount : Int = 0

访问:

//  通过类名访问类属性
Student.courseCount = 2
2016-09-01 16:05:13 qq_28379951 阅读数 254


// 1.创建一个类(class是Swift中的关键字,用于定义类
// Class 类名:继承的类
// 例如:类名-> LearningClass 父类:UIViewController
class LearningClass: UIViewController {
   // 定义类的属性方法
}

// 2.类可以添加属性方法 通常分为多种: 
// 存储属性:存储事例的常量和变量
// 计算属性:通过某种方式计算出来的属性
// 类属性: 与类自生相关的属性

// 2.1存储属性 最常用的属性,用户存储常量或变量,可以再创建时赋予初始值,也可以在初始化对象赋予值
// 列:
class Car {
    var car_Price: Int = 0
    var car_Name: String = ""
    var car_Weight: Double = 0.0
}

class CarViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        // 创建对象
        let car = Car()
        // 赋值对象属性
        car.car_Name = "QQ"   // 车名
        car.car_Price = 50000 // 价格
        car.car_Weight = 1.5  // 重量
    }
}
// 2.2 计算属性 存储的并不是实际值,而是提供getter/setter来间接获取/设置属性值
// 如果只提供getter方法,那么该属性便为只读属性
// 例:
class banana: NSObject {
    var unit_price: Double = 0.0
    var weight: Double = 0.0
    
    // 计算属性
    var allPrice: Double {
        get {
            return (unit_price * weight)
        } set {
            // newValue为系统分配的变量名,存储新值
            self.allPrice = newValue
        }
    }
}
// 2.3 类属性:需要通过 static 修改 与 OC static 类是
// 类属性是与类相关联的,而不是与类的实例相关联
// 所有的类和实例都共有一份类属性.因此在某一处修改之后,该类属性就会被修改
// 类属性的设置和修改,需要通过类来完成
// 例:
class Test: NSObject {
    // 类属性
    static var count: Int = 0
    // 与存储属性对比
    var count_1: Int = 0
}

class TestViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        // 类属性->重新赋值
        Test.count = 100
        // 输出值
        print(Test.count)
        
        // 存储属性->重新赋值
        let count_1 = Test()
        count_1.count_1 = 100
        // 输出值
        print(count_1.count_1)
    }
}

// 3.监听属性变化
// willSet:在属性值被存储之前设置。此时新属性值作为一个常量参数被传入。该参数名默认为newValue,我们可以自己定义该参数名
// didSet:在新属性值被存储后立即调用。与willSet相同,此时传入的是属性的旧值,默认参数名为oldValue
// willSet与didSet只有在属性第一次被设置时才会调用,在初始化时,不会去调用这些监听方法
// 例:
class Test1: NSObject {
    var age: Int? {
        willSet(newValue) {
            print("age 将要改变 \(age)")
            print("age 将要新值 \(newValue)")
        }
        
        didSet(oldValue) {
            print("age 已经改变 \(age)")
            print("age 已经新值 \(oldValue)")
        }
        /* 
        打印:
        age 将要改变 nil
        age 将要新值 Optional(23)
        age 已经改变 Optional(23)
        age 已经新值 nil
        */
    }
}

class Test1ViewController : UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        let obj = Test1()
        obj.age = 23
        print(obj.age)
    }
}

// 4.类的构造函数
// 4.1 构造函数类类似OC的构造方法,若没有调用构造函数系统也会提供默认的构造函数,同时也可以重写系统的构造方法

// 4.2 类的属性必须有值 
// 可以再构造函数中赋值 
// 也可以再初始化方法赋值

// 4.2.1 例:先在构造方法中赋值
class CarObj: NSObject {
    var name: String
    var price: Int
    
    // 重写父类的初始化方法
    override init() {
        name = ""
        price = 0
    }
}

// 4.2.2 例:在初始化方法中赋值
class CarObj1: NSObject {
    var name: String
    var price: Int
    
    init(name: String, price: Int) {
        self.name = name
        self.price = price
    }
}

class CarObj1ViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        let carObj1 = CarObj1(name: "QQ", price: 50000)
        print(carObj1)
    }
}

// 5.字典转模型(初始化时传入字典)
// 真实创建对象时,更多的是将字典转成模型
// 注意:
// 去字典中取出的是NSObject,任意类型.
// 可以通过as!转成需要的类型,再赋值(不可以直接赋值)

class CarObj2: NSObject {
    var name: String
    var price: Int
    
    init(dict : [String : NSObject]) {
        name = dict["name"] as! String
        price = dict["price"] as! Int
    }
}

class CarObj2ViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        let dict = ["name": "QQ", "price": 50000];
        let carObj2 = CarObj2(dict: dict)
        print(carObj2.name)
        print(carObj2.price)
    }
}

// 5.1字典转模型(利用KVC转化)
// 利用KVC字典转模型会更加方便
// 注意:
// KVC并不能保证会给所有的属性赋值
// 因此属性需要有默认值
// 基本数据类型默认值设置为0
// 对象或者结构体类型定义为可选类型即可(可选类型没有赋值前为nil)
class CarObj3: NSObject {
    var name: String?
    var price: Int = 0
    
    init(dict : [String : NSObject]) {
        super.init()
        setValuesForKeysWithDictionary(dict)
    }
}

class CarObj3ViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        let dict = ["name": "QQ", "price": 50000];
        let carObj3 = CarObj3(dict: dict)
        print(carObj3.name)
        print(carObj3.price)
    }
}

文章参考:http://www.jianshu.com/p/391dcd6b44af

2018-06-15 09:52:36 u012678352 阅读数 6206

类扩展, 为类添加属性

  • 如代码所示, 创建属性, 并实现set和get方法
  • 利用OC的runtime特性
private var kHJRefreshHeaderKey: String = ""
/// header
    var hj_header: HJRefreshHeaderView? {
        get {
            return (objc_getAssociatedObject(self, &kHJRefreshHeaderKey) as? HJRefreshHeaderView)
        }
        set(newValue) {
            objc_setAssociatedObject(self, &kHJRefreshHeaderKey, newValue, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN)
        }
    }
2019-04-29 13:50:16 understand_XZ 阅读数 904

我们在分类中添加存储属性时,往往会有一个 Extensions must not contain stored properties 的错误提醒,如下图:

解决这个问题就是给分类添加关联属性,主要用到的方法是:

public func objc_setAssociatedObject(_ object: Any, _ key: UnsafeRawPointer, _ value: Any?, _ policy: objc_AssociationPolicy)

public func objc_getAssociatedObject(_ object: Any, _ key: UnsafeRawPointer) -> Any?

为分类添加一个 UILabel 属性:

struct associatedKey {
     static var key = "xz_badge"
}      

private var xz_labelBadge: UILabel? {
        set {
            if let newValue = newValue {
                
                objc_setAssociatedObject(self, &(associatedKey.key), newValue, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN_NONATOMIC)
            }
        }
        
        get {
            return objc_getAssociatedObject(self, &(associatedKey.key)) as? UILabel
        }
    }   
    

调用

xz_labelBadge = UILabel()
// 创建
xz_labelBadge?.layer.cornerRadius = 10
xz_labelBadge?.layer.masksToBounds = true
xz_labelBadge?.backgroundColor = .red
xz_labelBadge?.font = UIFont.systemFont(ofSize: 10)
xz_labelBadge?.textAlignment = .center
xz_labelBadge?.frame = CGRect(x: CGFloat(x), y: CGFloat(y), width: 20, height: 20)
// 添加红点
self.addSubview(xz_labelBadge!)
                                 
                    

 

2016-10-30 19:51:47 wang631106979 阅读数 3951

OC中我们经常用到只读属性,用readonly修饰一下就行了,但在Swift中已经不是这样修饰的了,下面记录一下Swift中只读属性的使用

OC中的只读:

//只读属性
@property(readonly, nonatomic) NSObject *wcl;

Swift中的只读:

//只读属性
private(set) var wcl

Swift类方法

阅读数 320

swift 继承

阅读数 426

没有更多推荐了,返回首页