2016-08-18 27 views
104

में फ़ाइलप्रिवेट और निजी के बीच अंतर करने के लिए एक अच्छा उदाहरण क्या है में नए एक्सेस विनिर्देशकों को समझने में यह article उपयोगी रहा है। यह fileprivate और private के विभिन्न उपयोगों के कुछ उदाहरण भी प्रदान करता है।स्विफ्ट 3

मेरा प्रश्न है - fileprivate का उपयोग ऐसे फ़ंक्शन पर नहीं किया जा रहा है जो इस फ़ाइल में केवल private का उपयोग करने के समान ही उपयोग किया जा रहा है? एक ही स्रोत फ़ाइल से पहुँचा जा सकता:

उत्तर

212

fileprivate क्या private पहले स्विफ्ट विज्ञप्ति में हुआ करता था अब है। private के रूप में चिह्नित एक घोषणा को अब केवल उस व्याख्यात्मक दायरे में पहुंचा जा सकता है जिसमें इसे घोषित किया गया है। तो privatefileprivate से अधिक प्रतिबंधित है।

स्विफ्ट 4, एक प्रकार के भीतर निजी घोषणाएं उसी प्रकार के एक्सटेंशन तक पहुंच योग्य हैं यदि एक्सटेंशन को उसी स्रोत फ़ाइल में परिभाषित किया गया है।

उदाहरण (एक स्रोत फ़ाइल में सभी):

class A { 
    private func foo() {} 
    fileprivate func bar() {} 

    func baz() { 
     foo() 
     bar() 
    } 
} 

extension A { 
    func test() { 
     foo() // Swift 3: error: use of unresolved identifier 'foo' 
       // Swift 4: no error because extension is in same source file 
     bar() 
    } 
} 

let a = A() 
a.foo() // error: 'foo' is inaccessible due to 'private' protection level 
a.bar() 
  • निजी foo विधि केवल class A { ... } परिभाषा के दायरे के भीतर पहुंचा जा सकता है। यह से प्रकार के विस्तार तक भी पहुंच योग्य नहीं है (स्विफ्ट 3 में, स्विफ्ट 4 में परिवर्तनों के लिए नीचे दिया गया दूसरा नोट देखें)।

  • फ़ाइल-निजी bar विधि उसी स्रोत फ़ाइल से पहुंच योग्य है।

नोट्स:

  1. प्रस्ताव SE-0159 – Fix Private Access Levels स्विफ्ट 4 में स्विफ्ट 2 अर्थ विज्ञान पर वापस लौटने की तेज विकास मेलिंग सूची पर एक लंबी और विवादास्पद चर्चा के बाद सुझाव दिया, प्रस्ताव किया गया था rejected

  2. प्रस्ताव SE-0169 – Improve Interaction Between private Declarations and Extensions एक प्रकार एक ही प्रकार के विस्तार के लिए सुलभ अंदर private घोषणाओं बनाने के लिए करता है, तो विस्तार एक ही स्रोत फ़ाइल में परिभाषित किया गया है पता चलता है। इस प्रस्ताव को स्वीकार कर लिया और स्विफ्ट 4 में

+2

यदि आप स्वचालित रूप से स्विफ्ट 2 से 3 तक कोड परिवर्तित कर रहे हैं, तो एक्सकोड 'निजी' को 'fileprivate' में बदल देगा। हालांकि, अगर आपके पास हाथ से ऐसा करने की लक्जरी है, तो आप अक्सर 'निजी' को 'निजी' के रूप में छोड़ने से लाभ उठा सकते हैं ... यदि यह संकलित होता है, तो सब अच्छा है। –

1
class Privacy { 

    fileprivate(set) var pu:Int { 
     get { 
      return self.pr 
     } 
     set { 
      self.pr = newValue 
     } 
    } 
    private var pr:Int = 0 
    fileprivate var fp:Int = 0 


    func ex() { 
     print("\(self.pu) == \(self.pr) and not \(self.fp)") 
    } 
} 


extension Privacy { 

    func ex2() { 
     self.pu = 5 
     self.ex() 
    } 

} 

मुझे यह पसंद है क्योंकि यह ivars के लिए सुपर आसान है लागू किया गया था।

कोशिश निजी (और इसके विपरीत) fileprivate बदल रहा है और देखने के संकलन पर क्या होता है ...

4

अंगूठे का एक व्यावहारिक नियम यह है कि आप चर, स्थिरांक, भीतरी structs और वर्गों है कि केवल उपयोग किया जाता है के लिए निजी उपयोग करें अपनी कक्षा/संरचना की घोषणा के अंदर। आप उन फ़ाइलों के लिए fileprivate का उपयोग करते हैं जो आपके एक्सटेंशन के अंदर आपके वर्ग/स्ट्रक्चर के समान फ़ाइल के भीतर उपयोग किए जाते हैं, लेकिन उनके परिभाषित घुंघराले ब्रेसिज़ (यानी उनके व्याख्यात्मक दायरे) के बाहर।

class ViewController: UIViewController { 
     @IBOutlet var tableView: UITableView! 
     //This is not used outside of class Viewcontroller 
     private var titleText = "Demo" 
     //This gets used in the extension 
     fileprivate var list = [String]() 
     override func viewDidLoad() { 
      navigationItem.title = titleText 
     } 
    } 

    extension ViewController: UITableViewDataSource { 
     func numberOfSections(in tableView: UITableView) -> Int { 
      return list.count 
     } 
    } 
56

मैं बस, निजी fileprivate, खुले के बारे में एक चित्र आकर्षित, बंद

आशा है कि इसे जल्दी आप मदद कर सकते हैं, पाठ वर्णन के लिए देखें कृपया मार्टिन आर के जवाब

न्यू

सुल्तान के उत्तर के लिए धन्यवाद। यह चित्र केवल एक ही मॉड्यूल

enter image description here

+6

देखें, 'fileprivate' एक्सटेंशन से जुड़ा नहीं है लेकिन फ़ाइल में (किसी अन्य फ़ाइल में कक्षा ए के विस्तार को लिखने से' fileprivate' सदस्यों के उपयोग की अनुमति नहीं होगी) – Vince

+1

और thx @Vince भी मेरी गलती को सही करता है। :) –

+1

यह गलत लगता है। आप मुख्य बिंदु खो रहे हैं। आपको उसी मॉड्यूल के अंदर मौजूद कक्षाओं के बीच अंतर करना होगा और जो विभिन्न मॉड्यूल में हैं। यदि वे अलग-अलग मॉड्यूल में हैं तो 'सार्वजनिक' आपको विरासत में रखने की अनुमति नहीं देगा, इसलिए तीसरी छवि गलत है।साथ ही, यदि आप इसे देख सकते हैं तो आप हमेशा किसी भी कक्षा में विस्तार कर सकते हैं। एक्सटेंशन पर दृश्यता की व्याख्या करना तब बहुत अच्छा विचार नहीं है। – Sulthan

3

निम्न उदाहरण में पर काम करता है, भाषा private और fileprivate द्वारा संशोधित निर्माणों समान रूप से व्यवहार करने लगते हैं:

fileprivate func fact(_ n: Int) -> Int { 
    if (n == 0) { 
     return 1 
    } else { 
     return n * fact(n - 1) 
    } 
} 

private func gauss(_ n: Int) -> Int { 
    if (n == 0) { 
     return 0 
    } else { 
     return n + gauss(n - 1) 
    } 
} 

print(fact(0)) 
print(fact(5)) 
print(fact(3)) 

print(gauss(10)) 
print(gauss(9)) 

यह अंतर्ज्ञान के अनुसार है, मुझे लगता है। लेकिन, क्या कोई अपवाद है?

दयालु संबंध।

3

हालांकि @ मार्टिनआर और @ स्टीफन चेन का जवाब सही है, स्विफ्ट 4 चीजों को थोड़ा सा बदलता है।

निजी अब इसे उस वर्ग के लिए निजी माना जाता है जिसमें इसे घोषित किया जाता है और इसके विस्तार भी होते हैं।

फ़ाइलप्रिवेट उस फ़ाइल में निजी माना जाता है, यह एक वर्ग है जिसमें चर परिभाषित किया गया है, यह विस्तार है, या उसी फ़ाइल में परिभाषित कोई अन्य वर्ग है।

0

स्विफ्ट 4.0 में, निजी अब विस्तार में पहुंच योग्य है लेकिन उसी फ़ाइल में है। यदि आप यह घोषणा/अन्य फ़ाइल में विस्तार निर्धारित करते हैं तो अपने निजी चर नहीं अपने विस्तार के लिए सुलभ **

फ़ाइल निजी
फ़ाइल-निजी उपयोग के लिए अपने स्वयं को परिभाषित स्रोत फ़ाइल के लिए एक इकाई के उपयोग को प्रतिबंधित किया जाएगा। कार्यक्षमता के विशिष्ट टुकड़े के कार्यान्वयन विवरण को छिपाने के लिए फ़ाइल-निजी पहुंच का उपयोग करें, जब उन विवरणों का उपयोग पूरी फ़ाइल में किया जाता है।
सिंटेक्स:fileprivate <var type> <variable name>
उदाहरण:fileprivate class SomeFilePrivateClass {}


निजी
निजी पहुँच संलग्नित घोषणा करने के लिए एक इकाई के उपयोग को प्रतिबंधित है, और है कि एक ही में हैं कि घोषणा के विस्तार के लिए फ़ाइल। कार्यक्षमता के विशिष्ट टुकड़े के कार्यान्वयन विवरण को छिपाने के लिए निजी पहुंच का उपयोग करें, जब उन विवरणों का उपयोग केवल एक ही घोषणा के भीतर किया जाता है।
सिंटेक्स:private <var type> <variable name>
उदाहरण:private class SomePrivateClass {}


यहाँ सब पहुंच स्तर के बारे में और अधिक विस्तार है:
फ़ाइल:: ViewController.swift Swift - Access Levels

इस छवियों को देखो
यहां एक्सटेंशन और व्यू कंट्रोलर दोनों समान हैं फ़ाइल, इसलिए निजी चर testPrivateAccessLevel विस्तार में पहुँचा जा सकता है

enter image description here


फ़ाइल: TestFile.swift
यहाँ विस्तार और देखने नियंत्रक दोनों अलग अलग फ़ाइलों में हैं, इसलिए निजी चर testPrivateAccessLevel विस्तार में सुलभ नहीं है।

enter image description here

enter image description here


यहाँ वर्ग ViewController2ViewController का एक उपवर्ग है और दोनों एक ही फाइल में हैं। यहां निजी चर testPrivateAccessLevel सबक्लास में उपलब्ध नहीं है लेकिन उप-वर्ग में फ़ाइलप्रिवेट पहुंच योग्य है।

enter image description here

0

filePrivate - पहुँच नियंत्रण स्तर फ़ाइल के भीतर है।

मामले 1: हम एक ही कक्षा फ़ाइल में साथ एक्सटेंशन बनाने और इसके विस्तार में fileprivate समारोह या fileprivate संपत्ति तक पहुँचने का प्रयास करते हैं - उपयोग की अनुमति दी
मामले 2: हम नई फ़ाइल में वर्ग का एक एक्सटेंशन बनाते हैं तो - और अब fileprivate समारोह या fileprivate संपत्ति तक पहुँचने का प्रयास - पहुँच

अनुमति नहीं

निजी - अभिगम नियंत्रण के स्तर का शाब्दिक गुंजाइश

मामले 1 में साथ है: यदि संपत्ति या कार्य वर्ग में निजी के रूप में घोषित किया जाता है - तो स्कोप डिफ़ॉल्ट रूप से कक्षा है। केस 2: यदि फ़ंक्शन बॉडी में निजी उदाहरण घोषित किया गया है - तो उदाहरण का दायरा फ़ंक्शन बॉडी तक ही सीमित है।