ios - ما هو الفرق بين الصفات الذرية وغير الذرية؟


ما هو المتوسط atomic وغير atomic في تصريحات الملكية؟

@property(nonatomic, retain) UITextField *userName;
@property(atomic, retain) UITextField *userName;
@property(retain) UITextField *userName;

ما هو الفرق التشغيلي بين هؤلاء الثلاثة؟




Answers


آخر اثنين متطابقة. "الذري" هو السلوك الافتراضي ( لاحظ أنه ليس في الواقع كلمة رئيسية؛ يتم تحديدها فقط من خلال عدم وجود atomic - أضيف atomic ككلمة رئيسية في الإصدارات الأخيرة من لفم / عشيرة).

على افتراض أن كنتsynthesizing طريقة تنفيذ، الذرية مقابل غير الذرية التغييرات رمز ولدت. إذا كنت تكتب الخاص بك واضعة / الحاصل، الذرية / غير الذرية / الاحتفاظ / تعيين / نسخة هي مجرد استشارية. (ملاحظة:synthesize هو الآن السلوك الافتراضي في الإصدارات الأخيرة من لفم، وهناك أيضا لا حاجة للإعلان عن متغيرات المثيل؛ سيتم توليفها تلقائيا، أيضا، وسوف يكون لها _ مسبقا على اسمها لمنع الوصول المباشر العرضي).

مع "ذري"، فإن سيترز / جيتر توليف يضمن أن يتم إرجاع قيمة كاملة دائما من الحاضنة أو التي وضعتها واضعة، بغض النظر عن نشاط واضعة على أي موضوع آخر. وهذا هو، إذا كان الموضوع A في منتصف الحاضنة في حين يدعو الخيط B الضابط، وهي قيمة قابلة للحياة الفعلية - كائن أوتوريليسد، على الأرجح - سيتم إرجاعها إلى المتصل في A.

في غير nonatomic ، لا يتم تقديم مثل هذه الضمانات. وهكذا، غير الذرية أسرع بكثير من "الذرية".

ما "الذرية" لا تفعل هو تقديم أي ضمانات حول سلامة الموضوع. إذا كان الخيط A يستدعي الحاصل في وقت واحد مع الخيط B و C يستدعي الضابط بقيم مختلفة، قد يحصل مؤشر ترابط A على أي من القيم الثلاث التي تم إرجاعها - أي واحد قبل أي من المضامين يتم استدعاؤه أو تم تمرير أي من القيم إلى الخانات في B و C. وبالمثل، فإن الكائن قد ينتهي مع قيمة من B أو C، أي وسيلة ليقول.

يتم ضمان سلامة البيانات - واحدة من التحديات الرئيسية للبرمجة متعددة الخيوط - بوسائل أخرى.

إضافة إلى هذا:

atomicity خاصية واحدة أيضا لا يمكن ضمان سلامة الصفحات عندما متعددة الخصائص التابعة هي في اللعب.

يعتبر:

 @property(atomic, copy) NSString *firstName;
 @property(atomic, copy) NSString *lastName;
 @property(readonly, atomic, copy) NSString *fullName;

في هذه الحالة، يمكن إعادة تسمية الموضوع A الكائن عن طريق استدعاء setFirstName: ثم استدعاء setLastName: في هذه الأثناء، قد يقوم مؤشر الترابط B باستدعاء fullName بين مكالمات اثنين من مؤشر الترابط A وسيتلقى الاسم الأول الجديد مقترنا بالاسم الأخير القديم.

لمعالجة هذا، تحتاج إلى نموذج المعاملات . أي نوع آخر من المزامنة و / أو الاستبعاد يسمح لأحد باستبعاد الوصول إلى fullName أثناء تحديث الخصائص التابعة.




يتم شرح ذلك في وثائق أبل، ولكن أدناه بعض الأمثلة على ما يحدث في الواقع. لاحظ أنه لا توجد كلمة "ذرية"، إذا لم تحدد "غير ذري"، فإن الخاصية الذرية، ولكن تحديد "ذري" سيؤدي صراحة إلى حدوث خطأ.

//@property(nonatomic, retain) UITextField *userName;
//Generates roughly

- (UITextField *) userName {
    return userName;
}

- (void) setUserName:(UITextField *)userName_ {
    [userName_ retain];
    [userName release];
    userName = userName_;
}

الآن، البديل الذري هو أكثر تعقيدا قليلا:

//@property(retain) UITextField *userName;
//Generates roughly

- (UITextField *) userName {
    UITextField *retval = nil;
    @synchronized(self) {
        retval = [[userName retain] autorelease];
    }
    return retval;
}

- (void) setUserName:(UITextField *)userName_ {
    @synchronized(self) {
      [userName_ retain];
      [userName release];
      userName = userName_;
    }
}

في الأساس، فإن النسخة الذرية يجب أن تأخذ قفل من أجل ضمان سلامة الصفحات، وأيضا هو الاهتزاز عدد ريف على الكائن (و أوتوريليس العد لتحقيق التوازن في ذلك) بحيث يتم ضمان الكائن وجود للمتصل، وإلا هناك هي حالة سباق محتملة إذا كان مؤشر ترابط آخر هو تعيين القيمة، مما تسبب في عدد ريف لإسقاط إلى 0.

هناك في الواقع عدد كبير من المتغيرات المختلفة لكيفية عمل هذه الأشياء اعتمادا على ما إذا كانت الخصائص هي القيم العددية أو الكائنات، وكيفية الاحتفاظ بها، نسخ، للقراءة، غير الذرية، الخ التفاعل. بشكل عام المزج الملكية تعرف فقط كيفية القيام "الشيء الصحيح" لجميع تركيبات.




الذري

  • هو السلوك الافتراضي
  • سوف يضمن اكتمال العملية الحالية من قبل وحدة المعالجة المركزية، قبل عملية أخرى الوصول إلى المتغير
  • ليست سريعة، لأنه يضمن اكتمال العملية تماما

غير الذرية

  • ليس السلوك الافتراضي
  • أسرع (لتوليف رمز، وهذا هو، للمتغيرات التي تم إنشاؤها باستخدامproperty و @ سينثزيز)
  • لا موضوع آمنة
  • قد يؤدي إلى سلوك غير متوقع، عندما اثنين من عملية مختلفة الوصول إلى نفس المتغير في نفس الوقت



أفضل طريقة لفهم الفرق تستخدم المثال التالي.

لنفترض أن هناك خاصية سلسلة ذرية تسمى " [self setName:@"A"] "، وإذا قمت بالاتصال [self setName:@"A"] من الموضوع A، استدعاء [self setName:@"B"] من الموضوع B، وندعو [self name] [self setName:@"B"] [self name] من الموضوع C، ثم سيتم تنفيذ جميع العمليات على المواضيع المختلفة بشكل متسلسل مما يعني إذا كان موضوع واحد تنفيذ واضعة أو جيتر، ثم المواضيع الأخرى سوف تنتظر.

وهذا يجعل الخاصية "اسم" القراءة / الكتابة آمنة، ولكن إذا كان مؤشر ترابط آخر، D، يدعو [name release] وقت واحد ثم هذه العملية قد تنتج تحطم لأنه لا يوجد دعوة واضعة / جتر المعنية هنا. وهو ما يعني أن الكائن يقرأ / يكتب آمنا (أتوميك)، ولكن ليس مؤشر الترابط آمنا كما يمكن أن المواضيع الأخرى في وقت واحد إرسال أي نوع من الرسائل إلى الكائن. يجب على المطور ضمان سلامة الصفحات لهذه الكائنات.

إذا كان الخاصية "اسم" غير الذرية، ثم جميع المواضيع في المثال أعلاه - A، B، C و D سوف تنفذ في وقت واحد تنتج أي نتيجة لا يمكن التنبؤ بها. في حالة الذرية، إما واحدة من A، B أو C سوف تنفذ أولا، ولكن D لا يزال تنفيذ بالتوازي.




وقد تم تعريف بناء الجملة وعلم الدلالات جيدا من خلال إجابات ممتازة أخرى على هذا السؤال. لأن التنفيذ والأداء ليست مفصلة بشكل جيد، وسوف أضيف إجابتي.

ما هو الفرق الوظيفي بين هذه 3؟

كنت دائما تعتبر الذرية كما الافتراضي غريبة جدا. على مستوى التجريد ونحن نعمل في، وذلك باستخدام الخصائص الذرية لفئة كوسيلة لتحقيق 100٪ موضوع السلامة هو حالة الزاوية. لبرامج صحيح صحيح مؤشرات الترابط، والتدخل من قبل مبرمج يكاد يكون بالتأكيد شرطا. وفي الوقت نفسه، لم يتم بعد تفصيل خصائص الأداء والتنفيذ. بعد أن كتبت بعض البرامج ذات العلامات المتعددة بشكل كبير على مر السنين، كنت قد أعلن ممتلكاتي كما غير nonatomic طوال الوقت لأن الذري لم يكن معقولا لأي غرض من الأغراض. خلال مناقشة تفاصيل الخصائص الذرية وغير الذرية هذا السؤال ، فعلت بعض التنميط واجه بعض النتائج الغريبة.

إعدام

حسنا. أول شيء أود أن أوضحه هو أن تنفيذ القفل هو محدد ومحدد. يستخدم لويس @synchronized(self) في مثاله - لقد رأيت هذا كمصدر مشترك من الارتباك. التنفيذ لا يستخدم في الواقع @synchronized(self) . فإنه يستخدم مستوى الكائن تدور الأقفال . تصوير لويس هو جيد @synchronized(self) باستخدام @synchronized(self) ونحن جميعا على دراية، ولكن من المهم أن نعرف أنه لا يستخدم @synchronized(self) .

الفرق الآخر هو أن الخصائص الذرية ستحتفظ / تحرير دورة الأشياء الخاصة بك داخل الحاضنة.

أداء

وهنا الجزء مثيرة للاهتمام: الأداء باستخدام الوصول إلى الملكية الذرية في الحالات غير المتنازع عليها (على سبيل المثال واحد الخيوط) الحالات يمكن أن يكون حقا سريع جدا في بعض الحالات. في حالات أقل من مثالية، واستخدام الوصول الذرية يمكن أن يكلف أكثر من 20 أضعاف النفقات العامة من غير nonatomic . وفي حين كانت الحالة المتنازع عليها التي تستخدم 7 مواضيع أبطأ ب 44 مرة للهيكل الثلاثي البايتات (غز 2،7 كور i7 كواد كور، x86_64). البنية الثلاثية البايت مثال على خاصية بطيئة جدا.

ملاحظة جانبية مثيرة للاهتمام: كان المعرفون من قبل المستخدم من الهيكل ثلاثة بايت أسرع 52 مرات من الموصلات الذرية توليفها؛ أو 84٪ سرعة توليفات غير الذرية توليفها.

كائنات في القضايا المتنازع عليها يمكن أيضا أن تتجاوز 50 مرة.

نظرا لعدد التحسينات والاختلافات في عمليات التنفيذ، فإنه من الصعب جدا قياس الآثار في العالم الحقيقي في هذه السياقات. قد تسمع في كثير من الأحيان شيء مثل "تثق به، إلا إذا كنت الملف الشخصي وتجد أنها مشكلة". نظرا لمستوى التجريد، فإنه من الصعب جدا قياس التأثير الفعلي. استخلاص التكاليف الفعلية من التشكيلات يمكن أن يكون مضيعة للوقت جدا، ونظرا للاستخراج، غير دقيقة تماما. كذلك، أرك مقابل مرك يمكن أن تحدث فرقا كبيرا.

لذلك دعونا نعود إلى الوراء، وليس التركيز على تنفيذ الوصول إلى الملكية، ونحن سوف تشمل المشتبه بهم المعتادة مثل objc_msgSend ، وفحص بعض النتائج في العالم الحقيقي رفيعة المستوى للعديد من المكالمات إلى NSString جيتر في الحالات غير المتنازع عليها (القيم في ثوان):

  • مركز موارد المهاجرين | غير الذرية | نفذت يدويا حاصل: 2
  • مركز موارد المهاجرين | غير الذرية | توليف جيتر: 7
  • مركز موارد المهاجرين | ذرية | سينترزد جيتر: 47
  • أرك | غير الذرية | توليفها جيتر: 38 (ملاحظة: أرك إضافة ريف عدد الدراجات هنا)
  • أرك | ذرية | سينترزد جيتر: 47

كما كنت قد خمنت على الأرجح، مرجع العد النشاط / ركوب الدراجات هو مساهم كبير مع ذرات وتحت أرك. سترى أيضا اختلافات أكبر في القضايا المتنازع عليها.

على الرغم من أنني تولي اهتماما وثيقا للأداء، ما زلت أقول الدلالات أولا! . وفي الوقت نفسه، يعتبر الأداء أولوية منخفضة للعديد من المشاريع. ومع ذلك، معرفة تفاصيل التنفيذ وتكاليف التكنولوجيات التي تستخدم بالتأكيد لا يضر. يجب عليك استخدام التكنولوجيا المناسبة لاحتياجاتك، أغراضك وقدراتك. نأمل أن هذا سيوفر لك بضع ساعات من المقارنات، وتساعدك على اتخاذ قرار مستنير أكثر عند تصميم البرامج الخاصة بك.




الذرية = سلامة الموضوع

غير الذرية = لا سلامة الصفحات

سلامة الموضوع:

تكون متغيرات المثيل آمنة إذا كانت تتصرف بشكل صحيح عند الوصول إليها من مؤشرات ترابط متعددة بغض النظر عن جدولة أو تشذير تنفيذ سلاسل عمليات البحث هذه بواسطة بيئة التشغيل و بدون أي مزامنة إضافية أو تنسيق آخر على جزء من رمز الاتصال.

في سياقنا:

إذا قام مؤشر ترابط بتغيير قيمة المثيل القيمة التي تم تغييرها متاحة لكل مؤشرات الترابط، ويمكن تغيير مؤشر ترابط واحد فقط القيمة في المرة الواحدة.

حيث لاستخدام atomic :

إذا كان سيتم الوصول إلى متغير المثيل في بيئة مؤشرات الترابط.

تضمين atomic :

ليس بالسرعة غير nonatomic لأن غير الذرية لا تتطلب أي عمل الوكالة الدولية للطاقة على أن من وقت التشغيل.

حيث لاستخدام غير nonatomic :

إذا لم يتم تغيير متغير المثيل بواسطة مؤشرات ترابط متعددة يمكنك استخدامه. فإنه يحسن الأداء.




لقد وجدت شرحا جيدا وضع جيدا من الخصائص الذرية وغير الذرية هنا . في ما يلي بعض النصوص ذات الصلة:

'الذرية' يعني أنه لا يمكن تقسيمها. في شروط أوس / البرمجة دعوة وظيفة الذرية هي واحدة التي لا يمكن انقطاع - يجب تنفيذ الوظيفة بأكملها، وليس مبادلة من وحدة المعالجة المركزية من قبل السياق المعتاد أوس التحول حتى اكتمال. فقط في حال كنت لا تعرف: بما أن وحدة المعالجة المركزية يمكن أن تفعل سوى شيء واحد في وقت واحد، ونظام التشغيل بالتناوب الوصول إلى وحدة المعالجة المركزية لجميع العمليات قيد التشغيل في القليل من الوقت شرائح، لإعطاء وهم من تعدد المهام. يمكن جدولة وحدة المعالجة المركزية (ولا) يقطع عملية في أي مرحلة في تنفيذها - حتى في منتصف الدعوة وظيفة. لذا، بالنسبة إلى إجراءات مثل تحديث متغيرات العداد المشتركة حيث يمكن أن تحاول عمليتان تحديث المتغير في الوقت نفسه، يجب أن يتم تنفيذهما "بشكل ذري"، بمعنى أنه يجب إنهاء كل إجراء تحديث بالكامل قبل إجراء أي عملية أخرى على وحدة المعالجة المركزية.

لذلك سأكون تخمين أن الذرية في هذه الحالة يعني أنه لا يمكن وقف أساليب القارئ السمة - في الواقع يعني أن المتغير (ق) التي يقرأها الأسلوب لا يمكن تغيير قيمتها نصف الطريق من خلال لأن بعض آخر موضوع / دعوة / وظيفة يحصل تبادلت على وحدة المعالجة المركزية.

لأن المتغيرات atomic لا يمكن انقطاع، القيمة التي تحتوي عليها في أي لحظة هي (موضوع قفل) مضمونة لتكون غير معطلة ، على الرغم من أن ضمان هذا القفل موضوع يجعل الوصول إليها أبطأ. المتغيرات non-atomic ، من ناحية أخرى، لا تجعل مثل هذا الضمان ولكن لا توفر ترف وصول أسرع. وخلاصة القول، تذهب مع non-atomic عند معرفة المتغيرات الخاصة بك لن يتم الوصول إليها من قبل المواضيع متعددة في وقت واحد وسرعة الامور.




بعد قراءة الكثير من المقالات، كومة تجاوز المشاركات وجعل التطبيقات التجريبي للتحقق من سمات الملكية المتغيرة، قررت أن تضع جميع المعلومات سمات معا:

  1. atomic // افتراضي
  2. nonatomic
  3. strong = retain // افتراضي
  4. weak = unsafe_unretained
  5. retain
  6. assign // افتراضي
  7. unsafe_unretained
  8. copy
  9. readonly
  10. readwrite // افتراضي

في المقالة سمات الخصائص المتغيرة أو المعدلات في دائرة الرقابة الداخلية يمكنك أن تجد كل السمات المذكورة أعلاه، والتي من شأنها أن تساعد بالتأكيد لك.

  1. atomic

    • atomic يعني الوصول إلى مؤشر ترابط واحد فقط المتغير (نوع ثابت).
    • atomic هو موضوع آمن.
    • لكنه بطيء في الأداء
    • atomic هو السلوك الافتراضي
    • سوف يستخدم أسيسورس الذرية في بيئة جمع القمامة غير (أي عند استخدام الاحتفاظ / الإفراج / أوتوريليس) قفل للتأكد من أن مؤشر ترابط آخر لا تتداخل مع الإعداد الصحيح / الحصول على القيمة.
    • انها ليست في الواقع كلمة رئيسية.

    مثال:

        @property (retain) NSString *name;
    
        @synthesize name;
  2. nonatomic

    • nonatomic يعني الوصول متعددة الصفحات المتغير (نوع ديناميكي).
    • غير nonatomic هو موضوع غير آمنة.
    • لكنه سريع في الأداء
    • غير nonatomic غير السلوك الافتراضي. نحتاج إلى إضافة الكلمة الرئيسية غير nonatomic في الخاصية المميزة.
    • قد يؤدي إلى سلوك غير متوقع، عندما اثنين من عملية مختلفة (المواضيع) الوصول إلى نفس المتغير في نفس الوقت.

    مثال:

        @property (nonatomic, retain) NSString *name;
    
        @synthesize name;



أسهل إجابة أولا: ليس هناك فرق بين المثالين الثانيين. افتراضيا، موصلات الملكية هي الذرية.

سوف يستخدم أسيسورس الذرية في بيئة جمع القمامة غير (أي عند استخدام الاحتفاظ / الإفراج / أوتوريليس) قفل للتأكد من أن مؤشر ترابط آخر لا تتداخل مع الإعداد الصحيح / الحصول على القيمة.

راجع قسم " الأداء والتخييط " من وثائق أبل الهدف- C 2.0 لمزيد من المعلومات ولاعتبارات أخرى عند إنشاء تطبيقات متعددة الخيوط.




الذرية:

الضمانات الذرية أن الوصول إلى الممتلكات سوف يتم بطريقة ذرية. على سبيل المثال أنه دائما العودة الكائنات مبدئيا بالكامل، أي الحصول على / مجموعة من الخاصية على مؤشر ترابط واحد يجب أن تكتمل قبل آخر يمكن الوصول إليه.

إذا كنت تتخيل الدالة التالية التي تحدث على اثنين من المواضيع في وقت واحد يمكنك أن ترى لماذا النتائج لن تكون جميلة.

-(void) setName:(NSString*)string
{
  if (name)
  {
    [name release]; 
    // what happens if the second thread jumps in now !?
    // name may be deleted, but our 'name' variable is still set!
    name = nil;
  }

  ...
}

الايجابيات: عودة الأشياء مبدئيا بالكامل في كل مرة يجعلها أفضل خيار في حالة متعددة خيوط.

سلبيات: ضرب الأداء، يجعل التنفيذ أبطأ قليلا

غير الذرية:

على عكس الذرية، فإنه لا يضمن تماما عودة كائن تمهيده في كل مرة.

الايجابيات: التنفيذ السريع للغاية.

سلبيات: فرص قيمة القمامة في حالة متعددة خيوط.




الذرية تعني أن خيط واحد فقط يصل إلى المتغير (نوع ثابت). الذري هو موضوع آمنة، ولكن بطيئة.

غير الذرية يعني عدة مواضيع الوصول المتغير (نوع ديناميكي). غير الذرية هو موضوع غير آمنة، ولكنها سريعة.







الذري هو موضوع آمن ، أنها بطيئة ويؤكد جيدا (غير مضمونة) أن يتم توفير فقط قيمة مقفل بغض النظر عن عدد المواضيع تحاول الوصول عبر نفس المنطقة. عند استخدام ذري، يصبح جزء من التعليمات البرمجية مكتوبة داخل هذه الوظيفة جزء من القسم الحرج، الذي يمكن تنفيذ مؤشر ترابط واحد فقط في وقت واحد.

فإنه يؤكد فقط سلامة الصفحات؛ فإنه لا يضمن ذلك. ما أعنيه هو كنت استئجار سائق خبير بالنسبة لك السيارة، لا يزال لا يضمن سيارة لن تفي بحادث. ومع ذلك، يبقى احتمال أدنى.

الذرية - فإنه لا يمكن تقسيمها، وبالتالي فإن النتيجة المتوقعة. مع غير الذرية - عندما آخر الموضوع الوصول إلى منطقة الذاكرة يمكن تعديله، وبالتالي فإن النتيجة غير متوقعة.

كود تالك:

جعل جيتر الذرية و واضعة من موضوع الملكية آمنة. على سبيل المثال إذا كنت قد كتبت:

self.myProperty = value;

هو موضوع آمن.

[myArray addObject:@"Abc"] 

ليست موضوع آمن.




الافتراضي هو atomic ، وهذا يعني أنه لا يكلفك الأداء كلما كنت تستخدم الخاصية، ولكن هو موضوع آمن. ما الهدف-ج يفعل، يتم تعيين القفل، لذلك فقط مؤشر الترابط الفعلي قد الوصول إلى المتغير، طالما يتم تنفيذ واضعة / جيتر.

مثال مع مرك من الممتلكات مع إيفار _internal:

[_internal lock]; //lock
id result = [[value retain] autorelease];
[_internal unlock];
return result;

حتى هذين الأخيرين هي نفسها:

@property(atomic, retain) UITextField *userName;

@property(retain) UITextField *userName; // defaults to atomic

من ناحية أخرى لا غير nonatomic إضافة أي شيء إلى التعليمات البرمجية الخاصة بك. لذلك هو موضوع فقط آمنة إذا كنت رمز آلية الأمن نفسك.

@property(nonatomic, retain) UITextField *userName;

لا يجب كتابة الكلمات الرئيسية كخاصية مميزة لأول مرة على الإطلاق.

لا ننسى، هذا لا يعني أن الملكية ككل هي موضوع آمنة. فقط استدعاء الأسلوب من واضع / جيتر هو. ولكن إذا كنت تستخدم واضعة وبعد ذلك جتر في نفس الوقت مع 2 المواضيع المختلفة، فإنه يمكن كسر أيضا!




ذري (افتراضي)

الذري هو الافتراضي: إذا كنت لا تكتب أي شيء، الخاص بك هو ذري. ويضمن الملكية الذرية أنه إذا حاولت القراءة منه، سوف تحصل على قيمة صالحة. أنها لا تقدم أي ضمانات حول ما قد تكون القيمة، ولكن سوف تحصل على بيانات جيدة، وليس فقط الذاكرة غير المرغوب فيه. ما يسمح لك بذلك هو إذا كان لديك مؤشرات ترابط متعددة أو عمليات متعددة تشير إلى متغير واحد، يمكن قراءة مؤشر ترابط واحد ويمكن كتابة مؤشر ترابط آخر. إذا ضربوا في نفس الوقت، مضمون موضوع القارئ للحصول على واحدة من القيمتين: إما قبل التغيير أو بعد التغيير. ما الذري لا يعطيك أي نوع من الضمان حول أي من تلك القيم التي قد تحصل. وعادة ما يتم الخلط بين الذري وبين كونه خيطا للسلامة، وهذا ليس صحيحا. تحتاج إلى ضمان سلامة الصفحات الخاصة بك طرق أخرى. ومع ذلك، فإن الذرية تضمن أنه إذا حاولت قراءة، يمكنك الحصول على العودة نوعا من القيمة.

nonatomic

على الجانب الآخر، غير الذرية، كما يمكنك ربما تخمين، يعني فقط، "لا تفعل ذلك الاشياء الذرية". ما تخسره هو أن تضمن أنك دائما الحصول على العودة شيئا. إذا حاولت قراءة في منتصف الكتابة، هل يمكن أن نعود البيانات القمامة. ولكن، من ناحية أخرى، تذهب أسرع قليلا. لأن الخصائص الذرية يجب أن تفعل بعض السحر لضمان أنك سوف تحصل على قيمة، فهي أبطأ قليلا. إذا كان من الممتلكات التي كنت الوصول إلى الكثير، قد ترغب في المنسدلة إلى غير الذرية للتأكد من أنك لا تتكبد عقوبة السرعة.

اطلع على مزيد من المعلومات هنا: https://realm.io/news/tmi-objective-c-property-attributes/




إذا كنت تستخدم الممتلكات الخاصة بك في رمز متعدد الخيوط ثم سوف تكون قادرا على رؤية الفرق بين الصفات غير الذرية والذرية. غير الذرية أسرع من الذرية والذرية هو موضوع آمنة، وليس غير الذرية.

وقد أعطى فيجايندرا تريباثي مثالا على بيئة متعددة الخيوط.




قبل مناقشة حول سماتproperty، يجب أن تعرف ما هو استخدامproperty. property يقدم وسيلة لتحديد المعلومات التي تهدف فئة لتغليف. إذا قمت بتعريف كائن / متغير باستخدامproperty، فسيكون هذا الكائن / المتغير متاحا للفئات الأخرى التي تستورد فئته. إذا قمت بإعلان كائن باستخدامproperty في ملف الرأس، ثم عليك تجميعه باستخدامsynthesize في ملف التنفيذ.

مثال:

.h

@interface ExampleClass : NSObject
   @property (nonatomic, retain) NSString *name;
@end

.m

@implementation ExampleClass
   @synthesize name;
@end

الآن سوف مترجم توليف طرق أسيسور للاسم.

ExampleClass *newObject=[[ExampleClass alloc]init];
NSString *name1=[newObject name]; // get 'name'
[obj setName:@“Tiger”];

قائمة سماتproperty: الذرية. nonatomic. الاحتفاظ بها. نسخ. يقرأ فقط. قراءة و كتابة. تعيين. قوي.

الذرية: هو السلوك الافتراضي. إذا تم الإعلان عن شيء كذري ثم يصبح موضوع آمنة. يعني الموضوع-آمنة، في وقت واحد فقط مؤشر ترابط واحد من مثيل من تلك الفئة يمكن أن يكون لها السيطرة على هذا الكائن.

مثال:

@property NSString *name; //by default atomic
@property (atomic)NSString *name; // explicitly declared atomic

غير الذرية: انها ليست موضوع-- آمنة. يمكنك استخدام الخاصية المميزة غير الذرية لتحديد أن أسيسورس توليف ببساطة تعيين أو إرجاع قيمة مباشرة، مع عدم وجود ضمانات حول ما يحدث إذا تم الوصول إلى نفس القيمة في وقت واحد من مؤشرات الترابط مختلفة. لهذا السبب، فإنه من الأسرع للوصول إلى الملكية غير الذرية من الذرية. @property (nonatomic)NSString *name;

الاحتفاظ: مطلوب عندما تكون السمة مؤشر إلى كائن. الأسلوب سيتر زيادة الاحتفاظ عدد الكائن، بحيث أنه سيتم تشغيل الذاكرة في تجمع أوتوريليس. @property (retain)NSString *name;

نسخة: إذا كنت تستخدم نسخة، لا يمكنك استخدام الاحتفاظ. استخدام نسخة نسخة من فئة سوف تحتوي على نسختها الخاصة. حتى إذا تم تعيين سلسلة قابلة للتغيير ثم تغيرت بعد ذلك، يلتقط المثيل أي قيمة لها في الوقت الذي يتم تعيينه. لن يتم توليف أي طرق الضبط و جيتر.

@property (copy) NSString *name;

NSMutableString *nameString = [NSMutableString stringWithString:@"Liza"];    
xyzObj.name = nameString;    
[nameString appendString:@"Pizza"];

ريادونلي: إذا كنت لا تريد السماح بتغيير الخاصية بواسطة طريقة الضبط، يمكنك إعلان الخاصية قراءة. @property (readonly) NSString *name;

ريادوريت: هو السلوك الافتراضي. لا تحتاج إلى تحديد سمة ريادوريت صراحة.

@property (readwrite) NSString *name;

تعيين: سوف تولد اضع الذي يعين قيمة لمتغير المثال مباشرة، بدلا من نسخها أو الاحتفاظ بها. هذا هو أفضل لأنواع بدائية مثل NSInteger وCGFloat، أو الكائنات التي لا تملك مباشرة، مثل المندوبين.

@property (assign) NSInteger year;

قوية: لا بديل عن الاحتفاظ بها. @property (nonatomic, strong) AVPlayer *player;

unsafe_unretained: هناك فئات قليلة في الكاكاو والكاكاو اللمس التي لا تدعم بعد إشارات ضعيفة، مما يعني أنك لا يمكن أن تعلن خاصية ضعيفة أو ضعيفة المتغير المحلي لتتبع لهم. وتشمل هذه الفئات NSTextView، NSFont وNSColorSpace، الخ. إذا كنت بحاجة إلى استخدام مرجع ضعيفة إلى واحدة من هذه الفئات، يجب عليك استخدام إشارة غير آمنة. إشارة غير آمنة مشابه لإشارة ضعيفة لأنه لا يحفظ الكائن ذات الصلة على قيد الحياة، ولكن لن يتم تعيينها إلى لا شيء إذا تم يتم deallocated الكائن الوجهة.

@property (unsafe_unretained) NSObject *unsafeProperty;




  • -Atomic يعني واحد فقط الوصول موضوع متغير (نوع ثابت).
  • -Atomic هو موضوع آمن.
  • -ولكن كان بطيئا في الأداء

كيفية نعلن ما يلي:

كما الذري هو الافتراضي لذلك،

@property (retain) NSString *name;

وفي ملف التنفيذ

self.name = @"sourov";

لنفترض أن مهمة تتعلق ثلاث خصائص هي

 @property (retain) NSString *name;
 @property (retain) NSString *A;
 @property (retain) NSString *B;
 self.name = @"sourov";

جميع خصائص تعمل متزامن (مثل بشكل غير متزامن).

إذا كنت أسميه "اسم" من موضوع A ،

و

في نفس الوقت في حالة استدعاء

[self setName:@"Datta"]

من موضوع B ،

الآن إذا * اسم العقار nonatomic ثم

  • فإنه سيعود قيمة "داتا" لA
  • فإنه سيعود قيمة "داتا" لB

ولهذا السبب غير الذري يسمى موضوع غير آمنة ولكن ولكنه سريع في الأداء بسبب التنفيذ المتوازي

الآن إذا * خاصية اسم هي الذرية

  • وسوف يضمن قيمة "Sourov" لA
  • ثم فإنه سيعود قيمة "داتا" لB

هذا هو السبب الذري يسمى موضوع الآمن و هذا هو السبب يطلق عليه قراءة والكتابة آمنة

ومن شأن هذه العملية حالة أداء متسلسل. وبطيئة في الأداء

- Nonatomic يعني الوصول موضوع متعددة المتغير (النوع الديناميكي).

- Nonatomic هو خيط غير آمنة.

- لكنه سريع في الأداء

-Nonatomic وليس السلوك الافتراضي، نحن بحاجة إلى إضافة الكلمة nonatomic في سمة الممتلكات.

لفي تأكيد سويفت أن خصائص سويفت هي nonatomic بمعنى ObjC. أحد الأسباب هو حتى انك تعتقد حول ما إذا كان لكل خاصية atomicity غير كافية لتلبية الاحتياجات الخاصة بك.

إشارة: https://forums.developer.apple.com/thread/25642

جيئة وذهابا مزيد من المعلومات يرجى زيارة الموقع http://rdcworld-iphone.blogspot.in/2012/12/variable-property-attributes-or.html




قبل أن تبدأ: يجب أن تعرف أن كل كائن في الذاكرة يحتاج يمكن deallocated من الذاكرة لكتابة جديدة ليحدث. لا يمكنك ببساطة كتابة على أعلى شيء كما تفعل على الورق. أنت يجب محو أولا (dealloc)، وبعد ذلك يمكنك كتابة على ذلك. إذا كان في اللحظة التي يتم محو (أو نصف القيام به) وليس هناك ما تمت حتى الآن تم كتب (أو كتب نصف) ومحاولة قراءة يمكن أن يكون مشكلة كبيرة! مساعدة الذرية وnonatomic لك علاج هذه المشكلة بطرق مختلفة.

أولا قراءة هذا السؤال ثم قرأ الجواب Bbum ل . وبالإضافة إلى ذلك ثم قراءة ملخص بلدي.

atomic تضمن ALWAYS

  • إذا شخصين مختلفين يريدون القراءة والكتابة في نفس الوقت، والورق وليس فقط حرق! -> طلبك سوف تعطل أبدا، حتى في حالة تعارض.
  • إذا كان شخص واحد هو محاولة لكتابة وكتب فقط 4 من 8 رسائل إلى مكتوبة، ثم لا يمكن قراءة في الوسط، ويمكن أن يتم إلا القراءة عند كتابة كل الرسائل 8 -> لا قراءة (الحصول على) سيحدث يوم "الموضوع الذي لا يزال الكتابة"، أي إذا كان هناك 8 بايت بايت أن تكون مكتوبة، و4 بايت فقط مكتوبة - حتى تلك اللحظة، لا يسمح لك قراءة منه. ولكن منذ قلت انها لن تحطم ثم فإنه يقرأ من قيمة و autoreleased الكائن.
  • إذا قبل الكتابة لكم و محو ما كتب سابقا على الورق ومن ثم شخص ما يريد أن يقرأ لك أن لا يزال يقرأ. ماذا؟ وسوف يتم القراءة من شيء مماثل لنظام التشغيل Mac OS بن المهملات (كما المهملات بن يست يزال 100٪ محت ... انها في طي النسيان) ---> إذا ThreadA هو قراءة في حين dealloced ThreadB بالفعل لكتابة، هل يمكن إما الحصول على قيمة من قيمة مكتوبة بالكامل النهائية ThreadB أو الحصول على شيء من تجمع autorelease.

الاحتفاظ التهم هي الطريقة التي تدار الذاكرة في الهدف-C. عند إنشاء كائن، ولها الاحتفاظ العد 1. عند إرسال كائن على الاحتفاظ الرسالة، يتم زيادة الاحتفاظ به عدد بمقدار 1. عند إرسال كائن رسالة الإفراج عنهم، وdecremented الاحتفاظ به عدد بمقدار 1. عند إرسال كائن على رسالة autorelease ، وdecremented الاحتفاظ به عدد من 1 في مرحلة ما في المستقبل. إذا تم تخفيض عدد 0 تحتفظ object's، ويتم deallocated ذلك.

  • الذرية لا ضمان سلامة موضوع، وإن كان لها فائدة لتحقيق السلامة الموضوع. السلامة الموضوع نسبية لكيفية كتابة التعليمات البرمجية / أي قائمة انتظار موضوع كنت قراءة / كتابة من. فهو يضمن فقط خاصية تعدد غير crashable.

انتظر ماذا؟! وخاصية تعدد و السلامة موضوع مختلف؟

نعم فعلا.خاصية تعدد يعني: أن مواضيع متعددة قراءة قطعة مشتركة من البيانات في نفس الوقت ونحن لن تحطم الطائرة، إلا أنه لا يضمن أن كنت لا تقرأ من قيمة غير autoreleased. مع السلامة موضوع، ما يضمن أن ما تقرأ ليس اطلاق سراحهم لصناعة السيارات. والسبب أننا لا تجعل كل شيء الذري افتراضيا هو، لأن هناك تكلفة أداء وبالنسبة لمعظم الأشياء حقا لا تحتاج السلامة الموضوع. A أجزاء قليلة من التعليمات البرمجية لدينا في حاجة إليها وتلك الأجزاء القليلة نحن بحاجة إلى كتابة التعليمات البرمجية لدينا بطريقة موضوع آمنة باستخدام الأقفال، ومزامنة أو التزامن.

nonatomic

  • حيث لا يوجد شيء من هذا القبيل مثل ماك OS سلة المهملات، ثم لا أحد يهتم ما إذا كنت دائما الحصول على قيمة (<- هذا يمكن أن يؤدي إلى تعطل)، ولا أحد يهتم إذا كان شخص ما يحاول قراءة في منتصف الطريق من خلال تكتب (على الرغم من في منتصف الطريق الكتابة في ذاكرة مختلفة تماما عن الكتابة في منتصف الطريق على الورق، وعلى الذاكرة التي يمكن أن تعطيك قيمة غبي مجنون من قبل، بينما على الورق ترى سوى نصف ما كان كتب) -> لا يضمن أن لا تعطل، ل لا يستخدم آلية autorelease.
  • لا يضمن القيم مكتوبة بالكامل يجب أن تقرأ!
  • أسرع من ذرية

عموما أنها مختلفة في 2 جوانب:

  • تحطمها أم لا بسبب وجود أو عدم وجود تجمع autorelease.

  • السماح لأن تقرأ الحق في وسط "الكتابة لم تنتهي أو قيمة فارغة" أو عدم السماح، والسماح فقط لقراءة عند قيمة بالكامل مكتوب.




الخاصية الذرية يضمن الإبقاء على قيمة initialised تماما بغض النظر عن عدد المواضيع يفعلون جالبة واضعة على ذلك.

تحدد الخاصية nonatomic التي يمكنهم الدخول توليفها ببساطة تعيين أو إرجاع قيمة مباشرة، مع عدم وجود ضمانات حول ما يحدث إذا تم الوصول إلى تلك القيمة نفسها في وقت واحد من المواضيع المختلفة.




يعني الذرية مؤشر واحد فقط يمكن الوصول إلى متغير في كل مرة (نوع ثابت). الذرية هو الخيط آمنة، لكنه بطيء.

Nonatomic يعني أن مواضيع متعددة الوصول إلى متغير في الوقت نفسه (النوع الديناميكي). Nonatomic هو الخيط غير آمنة، لكنه سريع.




إذا كنت تستخدم الذري، وهو ما يعني ان موضوع تكون آمنة وللقراءة فقط. إذا كنت تستخدم nonatomic، فهذا يعني أن مواضيع متعددة الوصول إلى متغير وغير الموضوع غير آمنة، ولكن يتم تنفيذ ذلك بسرعة، فعلت عمليات القراءة والكتابة. هذا هو نوع الديناميكي.




الذرية: ضمان موضوع السلامة من خلال قفل موضوع استخدام NSLOCK.

غير الذرية: لا ضمان موضوع السلامة لعدم وجود آلية قفل الموضوع.




لتبسيط الارتباك كله دعونا نفهم قفل مزامنة lock.Mutex حسب اسم بتأمين التحولية من object.So إذا تم الوصول إلى الكائن فئة أي فئة أخرى يمكن الوصول إلى نفسsychronise object.In دائرة الرقابة الداخلية أيضا توفير مزامنة lock.Now أن تخدم في وضع FIFO ويضمن تدفق لا يتأثر فئتين تقاسم نفس instance.However إذا كانت المهمة على الترابط الرئيسي تجنب الكائن الوصول باستخدام خصائص نووية لأنها قد عقد UI وتدهور الأداء




والحقيقة هي أنها تستخدم تأمين زيادة ونقصان لتنفيذ الملكية الذرية. رمز على النحو التالي:

 static inline void reallySetProperty(id self, SEL _cmd, id newValue, 
      ptrdiff_t offset, bool atomic, bool copy, bool mutableCopy) 
    {
        id oldValue;
        id *slot = (id*) ((char*)self + offset);

        if (copy) {
            newValue = [newValue copyWithZone:NULL];
        } else if (mutableCopy) {
            newValue = [newValue mutableCopyWithZone:NULL];
        } else {
            if (*slot == newValue) return;
            newValue = objc_retain(newValue);
        }

        if (!atomic) {
            oldValue = *slot;
            *slot = newValue;
        } else {
            spin_lock_t *slotlock = &PropertyLocks[GOODHASH(slot)];
            _spin_lock(slotlock);
            oldValue = *slot;
            *slot = newValue;        
            _spin_unlock(slotlock);
        }

        objc_release(oldValue);
    }