سؤال

ماذا atomic و nonatomic يعني في خاصية الإعلانات?

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

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

هل كانت مفيدة؟

المحلول

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

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

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

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

ما يفعله "الذرية" ليس القيام به هو جعل أي ضمانات حول سلامة الخيط. إذا كان مؤشر الترابط، فهو يدعو Getter في وقت واحد مع موضوع B و C الذي يدعو STERTER مع قيم مختلفة، قد يحصل مؤشر الترابط على أي واحد من القيم الثلاث التي تم إرجاعها - الواحد قبل أي تعيينات يتم استدعاؤها أو إما من القيم التي تم تمريرها إلى Setters في 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 في ما بين الخيط، سيتلقى الاسم الأول الجديد إلى جانب الاسم الأخير القديم.

لمعالجة هذا، تحتاج إلى نموذج معاملات. وبعد أي نوع آخر من المزامنة و / أو الاستبعاد التي تسمح واحدة لاستبعاد الوصول إلى 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 و synthesize)
  • ليس الخيط آمن
  • قد يؤدي إلى سلوك غير متوقع، عندما وصول عملية مختلفة إلى نفس المتغير في نفس الوقت

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

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

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

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

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

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

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

تنفيذ

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

هناك اختلاف آخر هو أن الخصائص الذرية ستحتفظ / الإفراج عن كائناتك داخل Getter.

أداء

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

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

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

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

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

  • MRC |. nonatomic | تم تنفيذها يدويا Getters: 2
  • MRC |. nonatomic | Getter مرن: 7
  • MRC |. ذرية |. مروم Getter: 47
  • ARC |. nonatomic | Getter Synthesized Getter: 38 (ملاحظة: ARC يضيف المرفأ راكز ركوب الدراجات هنا)
  • ARC |. ذرية |. مروم Getter: 47

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

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

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

غير الذرية = لا سلامة الخيط

سلامة الخيط:

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

في سياقنا:

إذا تغير موضوع الخيط قيمة المثيل، فستكون القيمة المتغيرة لجميع المواضيع، ويمكن لخيط واحد فقط تغيير القيمة في وقت واحد.

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

إذا كان متغير المثيل قد يتم الوصول إليه في بيئة متعددة المراحل.

ضرر atomic:

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

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

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

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

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

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

بسبب ال 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 // تقصير

في المقالة سمات الممتلكات المتغيرة أو المعدلات في iOS يمكنك العثور على جميع السمات المذكورة أعلاه، وهذا بالتأكيد سيساعدك.

  1. atomic

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

    مثال:

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

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

    مثال:

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

atomic:

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

إذا كنت تتخيل الوظيفة التالية التي تحدث على مؤشر ترابطين بمجرد أن ترى لماذا لن تكون النتائج جميلة.

-(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;
  }

  ...
}

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

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

غير ذري:

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

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

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

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

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

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

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

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

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

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

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

الكلام رمز:

Atomic Make Getter و Serve of the Property Treate Safe. على سبيل المثال إذا كتبت:

self.myProperty = value;

هو خيط آمن.

[myArray addObject:@"Abc"] 

ليس خيط آمن.

لا يوجد مثل هذه الكلمة الرئيسية "الذرية"

@property(atomic, retain) UITextField *userName;

يمكننا استخدام ما سبق مثل

@property(retain) UITextField *userName;

انظر السؤال تجاوز مكدس أحصل على مشكلات إذا كنت أستخدم property (الذرية، الاحتفاظ) nsstring * myString.

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

مثال مع MRC من خاصية مع Ivar _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;

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

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

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

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

غير نشط

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

رؤية المزيد هنا: https://realm.io/news/tmi-objective-c-property-attribute/

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

قدمت Vijayendra Tripathi مثالا بالفعل على بيئة متعددة الخيوط.

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

كيف تعلن:

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

@property (retain) NSString *name;

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

self.name = @"sourov";

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

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

جميع الخصائص تعمل متوازية (مثل غير متزامن).

إذا اتصلت ب "الاسم" من الموضوع أ,

و

في نفس الوقت إذا اتصلت

[self setName:@"Datta"]

من الموضوع ب,

الآن إذا * اسم الملكية غير مرن ومن بعد

  • سيعود قيمة "داتا" ل
  • سيعود قيمة "DATTA" ل B

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

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

  • سوف تضمن القيمة "مصدر" ل
  • ثم سيعود قيمة "DATTA" ل B

لهذا السبب يسمى الذرية السلاح آمنة ولهذا السبب يسمى آمنة للقراءة

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

- nonatomic يعني موضوع متعدد الوصول إلى المتغير (النوع الديناميكي).

- غير مرخص هو موضوع غير آمن.

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

-الوناتوميك ليس السلوك الافتراضي، نحتاج إلى إضافة كلمة رئيسية غير مرئية في سمة الخاصية.

لأنه في Swift تأكيد أن العقارات SWIFT غير واضحة في إحساس OBJC. أحد الأسباب هو حتى تفكر في ما إذا كانت ذرية الملكية كافية لاحتياجاتك.

مرجع: https://forums.developer.apple.com/thread/25642.

جيئة وذهابا معلومات أكثر يرجى زيارة الموقعhttp://rdcworld-iphone.blogspot.inouring2/12/variable-property-attribute-or.html.

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

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


atomic سوف يضمن دائما

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

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

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

ماذا؟!هي خاصية تعدد ، موضوع سلامة مختلفة ؟

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


nonatomic

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

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

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

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

تضمن الممتلكات الذرية الاحتفاظ بقيمة مهدئة بالكامل بصرف النظر عن عدد المواضيع التي تقوم بها Getter & Sedter عليه.

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

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

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

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

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

غير نشط

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

مجاملة https://academy.realm.io/posts/tmi-objective-c-property-attribute/

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

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

مجاملةhttps:/medium.com/@yogevsitton/atomic-vs-non-atomic-properties-crash-course-d11c23f4366c.

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

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

 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);
    }

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

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

لتبسيط الارتباك بأكمله، دعونا نفهم قفل mutex.

قفل MUTEX، حسب الاسم، يغلق تغيير الكائن. لذلك إذا تم الوصول إلى الكائن من خلال فئة، فلن يتمكن أي فئة أخرى من الوصول إلى نفس الكائن.

في iOS، @sychronise يوفر أيضا قفل MUTEX. كما أنه يعمل في وضع FIFO ويضمن أن التدفق لا يتأثر بفصلتين تقاسم نفس الحالة. ومع ذلك، إذا كانت المهمة موجودة في الخيط الرئيسي، فقم بتجنب الوصول إلى الكائن باستخدام الخصائص الذرية لأنه قد يحمل UI وخفض الأداء.

Atomic: ضمان أمان الخيارات عن طريق قفل الخيط باستخدام NSLOCK.

غير الذرية: لا يضمن سلامة الخيارات لأنه لا توجد آلية قفل الخيط.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top