2015-10-24 61 views
1

在Objective-C:如何在不觸發didSet觀察者的情況下在Swift類的內部方法中設置屬性?

@interface User : NSObject 
@property (nonatomic, strong) NSString *name; 

- (void)setName:(NString *newName) { 
    _name = newName 
    NSLog("newName = %@", newName); 
} 

User *user = [[User alloc] init]; 
user.name = @"Test"; // Call setName method and log "newName = Test" 

但在用戶類的內部方法:

_name = "Test"; // Don't call setName 

在夫特:

class User : NSObject 
var name: String { 
    didSet { 
     print("newName = " + name) 
    } 
} 

如何在內部方法集名User類沒有觸發didSet觀察者?像Objective-C中的_name = @"Test"一樣?

回答

4

您無法阻止didSet被調用。但是,如果你想出於某種原因重新創建直接在Objective-C中調用實例變量的機制,避免使用setter,那麼可以使用計算/存儲屬性對。

例如:

class User { 
    private var _name: String = "" 

    var name: String { 
     get { 
      return _name 
     } 
     set { 
      // any willSet logic 
      _name = newValue 
      // any didSet logic 
     } 
    } 
} 

在本質上,這實際上是大約正是你實際上得到Objective-C中,當你創建一個屬性。

0

the Swift docs來自:

迅速屬性不具有相應的實例變量,並且後備存儲屬性不直接訪問。這種方法避免了在不同情況下如何訪問價值以及將財產的聲明簡化爲單一的明確聲明的混淆。

和:每當屬性分配一個新值

爲totalSteps的willSet和didSet觀察員調用。即使新值與當前值相同,情況也是如此。

有沒有精確的類比支持整合到Swift中的變量。您可以複製Objective-C屬性(請參閱nhgrif的答案)。不過,這種方法在Swift中是陌生的,對未來的程序員來說可能很難理解。如果你不想做,你既可以將您的didSet代碼到一個單獨的功能...

class User : NSObject { 
    var name: String = "" 

    func setNameAndPrint(name newName : String) { 
     name = newName 
     print("newName = " + name) 

    } 
} 

let user = User() 

user.name = "Aaron" // doesn't print anything 
user.setNameAndPrint(name: "Zhao Wei") // prints "newName = Zhao Wei" 

...或者你可以寫更明確的代碼來模仿這種行爲......

class User : NSObject { 
    var printNameAfterSetting = true 

    var name: String = "" { 
     didSet { 
      if printNameAfterSetting { 
       print("newName = " + name) 
      } else { 
       printNameAfterSetting = true 
      } 
     } 
    } 
} 

let user = User() 

user.printNameAfterSetting = false 
user.name = "Aaron" // prints nothing 
user.name = "Zhao Wei" //prints "newName = Zhao Wei" 

這示例使用bool,但可以使用枚舉或其他類型來表示更復雜的邏輯,具體取決於您的用例。

+0

'「沒有確切的比喻。」我傾向於不同意。我的答案*中的例子與您在聲明「@屬性」時在Objective-C中得到的內容完全類似。它只需要更多的代碼在Swift中。但事實證明,在大多數情況下,'willSet'或'didSet'實際上就是所有需要的。 – nhgrif

+0

你是對的;我會更新。 –

相關問題