Hello our valued visitor, We present you the best web solutions and high quality graphic designs with a lot of features. just login to your account and enjoy ...
Hello our valued visitor, We present you the best web solutions and high quality graphic designs with a lot of features. just login to your account and enjoy ...
| رقم الخبر | عنوان الخبر | التفاصيل |
|---|---|---|
| 22,633 | الدرس 18: ما بين النسخ (Copying) والإسناد (Assignment) في Cpp |
عامل الإسناد (Assignment Operator)
يُستخدم "عامل الإسناد" لإحلال بيانات كائن ما مكان بيانات كائن موجود سلفًا (مُهيّأ مُسبقًا). انظر المثال التالي: // عامل الإسناد #include <iostream> #include <string> using std::cout; using std::endl; class Foo { public: Foo(int data) { this -> data = data; }~Foo() {}; Foo & operator = (const Foo & rhs) { data = rhs.data; return *this; } int data; }; int main() { Foo foo(2); // Foo(int data) استدعاء Foo foo2(42); foo = foo2; // استدعاء عامل الإسناد cout << foo.data << endl; // 42 }تستطيع هنا أن تلاحظ أنّنا استدعينا عامل الإسناد بعد أن هيّئنا الكائن foo، ثم نسند بعد ذلك foo2 إلى foo، وتكون جميع التغييرات التي ستحدث عند استدعاء عامل الإسناد مُعرّفة في الدالة operator=. انظر هذا المثال الحي. منشئ النسخ (Copy Constructor)مُنشئ النَّسخ من ناحية أخرى على النقيض من عامل الإسناد، إذ يُستخدم لتهيئة كائن غير موجود مسبقًا (أو غير مهيّأ مسبقًا)، هذا يعني أنه ينسخ جميع البيانات من الكائن الذي يُسند إليه، دون تهيئة الكائن الذي يتم نسخه بالفعل. دعنا نلقي نظرة على نفس الشيفرة أعلاه ولكن مع استخدام مُنشئ النسخ بدلًا من منشئ الإسناد: //منشئ النسخ #include <iostream> #include <string> using std::cout; using std::endl; class Foo { public: Foo(int data) { this -> data = data; }~Foo() {}; Foo(const Foo & rhs) { data = rhs.data; } int data; }; int main() { Foo foo(2); //Foo(int data) استدعاء Foo foo2 = foo; // استدعاء منشئ النسخ cout << foo2.data << endl; }في التعبير Foo foo2 = foo; في الدالّة الرئيسية، أسندنا الكائن على الفور قبل تهيئته، ما يعني أنه مُنشِئ نسخ، لكن لاحظ أنّنا لم نكن بحاجة إلى تمرير المعامل (int) للكائن foo2، لأننا سحبنا البيانات السابقة تلقائيًا من الكائن foo. انظر هذا المثال الحي للمزيد. مُنشئ النسخ مقابل منشئ الإسنادبعد هذه النظرة السريعة على مفهومي مُنشئ النسخ ومنشئ الإسناد ورؤية مثال عن عمل كلٍ منهما، سننظر الآن كيف يمكن استخدامهما معًا في نفس الشيفرة: // منشئ النسخ مقابل منشئ الإسناد #include <iostream> #include <string> using std::cout; using std::endl; class Foo { public: Foo(int data) { this -> data = data; }~Foo() {}; Foo(const Foo & rhs) { data = rhs.data; } Foo & operator = (const Foo & rhs) { data = rhs.data; return *this; } int data; }; int main() { Foo foo(2); //Foo(int data) استدعاء المنشئ العادي Foo foo2 = foo; // استدعاء منشئ النسخ cout << foo2.data << endl; Foo foo3(42); foo3 = foo; // استدعاء منشئ الإسناد cout << foo3.data << endl; }الناتج: 2 2لقد استدعينا في البداية مُنشئ النسخ عن طريق التعبير Foo foo2 = foo; لأننا لم نهيّئه من قبل، ثم استدعينا بعد ذلك عامل الإسناد على foo3 لأنه سبقت تهيئته (foo3=foo). هذا الدرس جزء من سلسلة دروس عن C++. ترجمة -بتصرّف- للفصل Chapter 29: Copying vs Assignment من كتاب C++ Notes for Professionals |
| 22,632 | 10 تطبيقات و 7 ألعاب أندرويد مدفوعة متاحة الآن مجانًا |
مجموعة جديدة من تطبيقات و ألعاب أندرويد المدفوعة ولكنها متاحة حاليًا مجانًا ولفترة محدودة، بالتالي ستكون هذه المجموعة صفقة كبيرة لمستخدمي النظام المذكور، والآن دعونا نبدأ مباشرة بذكر هذه الألعاب والتطبيقات ( 10 تطبيقات و 7 ألعاب أندرويد). 10 تطبيقات
التدوينة 10 تطبيقات و 7 ألعاب أندرويد مدفوعة متاحة الآن مجانًا ظهرت أولاً على عالم التقنية. |
| 22,631 | JioMeet بمثابة نسخة مجانية من تطبيق مؤتمرات الفيديو Zoom |
مع تفشي جائحة كورونا حول العالم، استحوذت خدمة Zoom على عالم مؤتمرات الفيديو ، وهذا استدعى من باقي الشركات النظر إلى خدماتها وتقديم المزيد من الدعم، على سبيل المثال، خدمتي Meet و Duo من جوجل وخدمة Teams من مايكروسوفت، الآن هناك خدمة أخرى جديدة سيكون لها مكان كبير في عالم مؤتمرات الفيديو والمتمثّلة في خدمة JioMeet. ويمكننا أن نُلخّص مجموعة ميزات وواجهة تطبيق JioMeet بمميزات وواجهة الخدمة الأخرى Zoom، بمعنى آخر، إذا كنت قد استخدمت Zoom فمن المؤكد أنك ستشعر وكأنك في المنزل مع JioMeet، ويكمُن الاختلاف في تحقيق الدخل، حيث أن Zoom تضع بعض المميزات خلف الاشتراك، أما JioMeet فهي مجانية وبشكل كامل. وعندما يتعلق الأمر بما تُقدّمه خدمة JioMeet من مميزات، فيُمكِنُكَ معها الحصول على مكالمة جماعية لحد أقصى 100 شخص وبجودة 720p HD، ويمكن أن تصل مدة المكالمات إلى 24 ساعة، وهناك الدعم لتسجيل الدخول المتعدد بين الأجهزة والتبديل السلس، ويمكنك تمكين غرف الانتظار حتى تتمكن من تحديد من يمكنه الانضمام إلى مكالمتك. أخيرًا، تتوفّر خدمة JioMeet كتطبيق على نظامي أندرويد و iOS وأنظمة تشغيل سطح المكتب المعروفة، ومنذ إطلاقها حصدت على أندرويد فقط على أكثر من 10.000 عملية تثبيت، وطبعًا الرقم سيتضعاف أضعافًا عندما نُضيف عمليات التنزيل من أنظمة التشغيل الاخرى. تحميل تطبيق JioMeet على أندرويد. المصدر: التدوينة JioMeet بمثابة نسخة مجانية من تطبيق مؤتمرات الفيديو Zoom ظهرت أولاً على عالم التقنية. |
| 22,630 | آبل تطلق بوابة إلكترونية لمتابعة معاملات Apple Card على غرار تطبيق المحفظة |
أطلقت شركة آبل بوابة إلكترونية جديدة تتيح لمالكي بطاقتها الإئتمانية Apple Card من متابعة إجراءاتهم المالية والمدفوعات ومراقبة الرصيد على غرار إمكانية الوصول المتاحة أصلاً عبر تطبيق المحفظة Wallet App. وبجانب إمداد البوابة مالكي البطاقات بهذه الطريقة للدفع وعرض بيانات بطاقاتهم على أجهزة الحاسوب؛ توفر البوابة تنزيل كشف حساب للرصيد والمعاملات السابقة على هيئة ملف PDF. كما توفر طريقة لجدولة المدفوعات وكذلك إمكانية ربط أو إزالة الحسابات البنكية، مع خدمة دعم أيضاً تلبي استفسارات العملاء. وبالمناسبة كان توفير طريقة مغايرة للإطلاع والوصول لبيانات بطاقة آبل Apple Card مطلباً من المستخدمين منذ إطلاق البطاقة أغسطس الماضي نظراً لما في ذلك من تسهيل لعمليات المتابعة للإجراءات المالية وخصوصاً في حالات يصعب فيها الوصول للهاتف أو عند فقدانه. وكانت آبل قد أطلقت بطاقاتها الإئتمانية العام الماضي بالتعاون مع بنك Goldman Sachs كبطاقة دفع تتبع التقنيات الحديثة وتوفر للمستخدمين طريقة دفع عبر الهاتف بدون أي رسوم للمعاملات أو تلك الأخرى التي تفرض على التأخير بل تكتفي بمعدل الفائدة. بينما توفر في نفس الوقت العديد من المحفزات عبر إعادة نسبة من قيمة المشتريات التي تتم عبر البطاقة في جال الشراء من متاجر آبل أو أحد الشركاء التي تعقد معهم الشركة اتفاقات للتشيجع على استحدام البطاقة. مواضيع ذات صلة: آبل تتخلص من ميزة Force Touch في نسخة نظام الساعة watchOS 7 المصدر
التدوينة آبل تطلق بوابة إلكترونية لمتابعة معاملات Apple Card على غرار تطبيق المحفظة ظهرت أولاً على عالم التقنية. |
| 22,596 | نظام بيدو ـ أداة الصين لكسر الهيمنة الأمريكية في الفضاء؟ | بإطلاقها للقمر الصناعي الخامس والثلاثين والأخير لنظام الملاحة وتحديد المواقع "بيدو" تكون الصين قد أكملت تغطية هذا النظام لكامل الكرة الأرضية، مُعززة بذلك مكانتها وقدراتها كقوة فضائية صاعدة على المستويين المدني والعسكري. |
| 22,595 | كيف تعمل ميزة Car Key الجديدة؟ ومتى ستتمكن من استخدامها؟ |
أعلنت شركة آبل عن ميزة Car Key في نظامي (iOS 14) و(iOS 13) خلال مؤتمر المطورين السنوي، كما أعلنت الشركة عن العديد من المزايا الجديدة في نظام (iOS 14). كيف تعمل ميزة Car Key الجديدة؟باستخدام هذه الميزة يمكن للسائقين استبدال المفاتيح الفعلية بأجهزة آيفون الخاصة بهم، وكما أوضحت آبل خلال الكلمة الرئيسية في (WWDC 2020)، يمكنك ببساطة حمل هاتفك الآيفون بالقرب من مقبض باب السيارة لفتحه باستخدام تقنية (NFC). بمجرد دخولك للسيارة، ضع جهاز آيفون في قارئ (NFC) أو الشاحن اللاسلكي لبدء تشغيل السيارة، وإذا كان لديك هاتف "آيفون 11" أو إصدار أحدث، فلن تضطر حتى إلى إخراجه من جيبك لفتح الأبواب أو تشغيل السيارة، وذلك بفضل شريحة (U1). لا تتطلب ميزة Car Key المصادقة بشكل افتراضي، لذلك يمكن أن تعمل بنقرة واحدة فقط، لكن آبل تضمن أن تكون العملية آمنة وتستند إلى رمز مميز فريد يتم مشاركته بين هاتف آيفون وسيارتك، حيث يستخدم نظام (iOS) موقعك ومعلومات (Apple ID) لمنع عمليات الاحتيال. ومع ذلك، إذا لم تكن مرتاحًا مع الوضع السريع، فيمكنك تعطيله لطلب مصادقة (Face ID أو Touch ID) لفتح السيارة وتشغيلها، كما يمكنك أيضًا إضافة ميزة Car Key إلى (Apple Watch)، مما يجعل استخدام هذه الميزة أسهل. حتى إذا نفدت بطارية هاتفك، فسوف تعمل الميزة لمدة تصل إلى 5 ساعات إضافية من خلال وضع (Power Reserve). كيفية إضافة ميزة Car Key؟تتم إدارة الميزة من خلال تطبيق (Wallet) على هواتف آيفون، ولكن يجب عليك أيضًا تثبيت تطبيق الشركة المصنعة للسيارة لكي يعمل كل شيء. في وقت سابق من اليوم، حدّثت (BMW) تطبيق (Connected) للسماح للمستخدمين بإعداد ميزة Car Key باستخدام هاتف آيفون. يجب عليك وضع جهازك الآيفون في قارئ (NFC) للسيارة أثناء الإعداد الأول، حيث سيحدد نظام (iOS) سيارتك ويعيد توجيهك إلى تطبيق الشركة المصنعة للسيارة لإكمال العملية. إذا فشلت عملية الإقران التلقائية، يمكن للمستخدمين إضافة ميزة Car Key يدويًا باستخدام رمز (PIN) الذي تم إنشاؤه بواسطة تطبيق الشركة المصنعة للسيارة. يمكن للمستخدمين مشاركة مفاتيح سياراتهم من خلال الميزة الجديدة مع ما يصل إلى خمسة أشخاص من خلال (iMessage)، كما يمكن تحديد ما إذا كان كل شخص تمت دعوته سيكون له حق الوصول الكامل إلى السيارة أو إذن فقط لفتح الأبواب. الأجهزة المتوافقة مع ميزة آبل الجديدة:• iPhone XR لن تعمل كل سيارة مع هذه الميزة الجديدة.،كما أن (BMW) هي أول شركة تصنيع سيارات تعلن عن دعم هذه الميزة الجديدة، وهي تضيف الميزة إلى نماذج (1 و 2 و 3 و 4 و 5 و 6 و 8 و X5 و X6 و X7 و X5M و X6M و Z4) المصنعة بعد 1 يوليو 2020. التوافر:وعلى الرغم من الإعلان عن ميزة Car Key كميزة جديدة لنظام (iOS 14)، إلا أنها ستكون متاحة أيضًا للمستخدمين خلال هذا الشهر على نظام (iOS 13.6). لم تحدد آبل تاريخ إصدار لنظام التشغيل (iOS 13.6) الذي يتوفر حاليًا كإصدار تجريبي، لكن من المحتمل أن يتم إصدار التحديث للجمهور في الأيام القادمة. |
| 22,580 | 8 نصائح لتنظيم تطبيقاتك في هاتف آيفون |
يمكن أن يكون تنظيم الشاشة الرئيسية لهاتف آيفون أو جهاز آيباد تجربة غير سارة، حتى إذا كان لديك تخطيط في ذهنك، فإن نهج آبل الصارم لوضع الرموز يمكن أن يكون غير دقيق ومحبط. لحسن الحظ، سيجعل نظام (iOS 14) الشاشة الرئيسية في هاتف آيفون أفضل بكثير، لكن حتى حصولك على التحديث الجديد إليك بعض النصائح لتنظيم تطبيقاتك وإيجاد مساحة أكبر في الشاشة الرئيسية. كيفية تنظيم الشاشة الرئيسية في هاتف آيفون:لإعادة ترتيب رموز التطبيقات على الشاشة الرئيسية في هاتف آيفون انقر مع الاستمرار فوق أحد الرموز حتى تبدأ جميع الرموز بالاهتزاز، كما يمكنك أيضًا الضغط مع الاستمرار على أحد الرموز، ثم النقر فوق (تحرير الشاشة الرئيسية) في القائمة التي تظهر، بعد ذلك، ابدأ في سحب الرموز أينما تريد على الشاشة الرئيسية. التطبيقات المهمة على الشاشة الرئيسية الأولى:لا يتعين عليك ملء شاشة رئيسية كاملة قبل الانتقال إلى الشاشة التالية، هذه طريقة مفيدة أخرى لإنشاء التقسيمات بين أنواع معينة من التطبيقات، على سبيل المثال، يمكنك وضع التطبيقات التي تستخدمها غالبًا في (Dock) وأي تطبيقات متبقية على شاشتك الرئيسية. عندما تفتح جهازك، تكون الشاشة الرئيسية هي أول ما تراه، حيث يمكنك تحقيق أقصى استفادة من هذه المساحة عن طريق وضع التطبيقات التي تريد الوصول إليها بسرعة على الشاشة الأولى. وضع المجلدات في (Dock):إحدى الطرق لجعل (Dock) أكثر فائدة هي وضع مجلدات فيه، حيث يعتمد معظم الأشخاص على (Dock) للوصول إلى تطبيقات مثل الرسائل أو متصفح سفاري أو البريد، لذلك يمكنك إنشاء المجلدات في (Dock) على هاتف آيفون أو جهاز آيباد لتسهيل عملية الوصول للتطبيقات. تنظيم المجلدات حسب نوع التطبيقات:الطريقة الأكثر وضوحًا لتنظيم تطبيقاتك في هاتف آيفون هي تقسيمها حسب الغرض إلى مجلدات، حيث يعتمد عدد المجلدات التي ستحتاجها على عدد التطبيقات لديك وما تفعله وعدد مرات الوصول إليها. سيكون إنشاء نظام خاص بك مصمم لسير عملك هو أفضل شيء، لذلك انظر إلى تطبيقاتك وتعرف على كيفية تجميعها بطرق عملية وذات مغزى. تنظيم المجلدات بناءً على الإجراءات:يمكنك تصنيف التطبيقات في هاتف آيفون استنادًا إلى الإجراءات التي تساعدك على تنفيذها، حيث قد تتضمن بعض تصنيفات المجلدات الدردشة أو البحث أو التشغيل. الترتيب الأبجدي:يعد تنظيم تطبيقاتك أبجديًا خيارًا آخر، حيث يمكنك القيام بذلك بسهولة بالغة في هاتف آيفون وذلك عن طريق إعادة تعيين الشاشة الرئيسية، ما عليك سوى الانتقال إلى (الإعدادات) ثم (عام) ثم (إعادة تعيين) ثم (إعادة تعيين تخطيط الشاشة الرئيسية). ستظهر التطبيقات على الشاشة الرئيسية الأولى، لكن سيتم سرد كل شيء آخر أبجديًا، كما يمكنك إعادة التعيين في أي وقت لإعادة تنظيم التطبيقات. تنظيم أيقونات التطبيقات حسب اللون:ربما تقوم بالفعل بربط تطبيقاتك المفضلة بلون أيقوناتها، لكن عندما تبحث عن تطبيق (Evernote)، قد تبحث عن مستطيل أبيض ونقطة خضراء، لكن من السهل العثور على تطبيقات مثل (Strava) أو تويتر لأن علامتها التجارية القوية والحيوية تبرز حتى على الشاشة الرئيسية المزدحمة. يعتبر تجميع التطبيقات حسب اللون خيار أساسي للتطبيقات التي تختار عدم الاحتفاظ بها في المجلدات، بالإضافة إلى ذلك سيعمل تنظيم أيقونات التطبيقات حسب اللون بشكل جيد فقط مع التطبيقات التي تستخدمها على هاتف آيفون في أغلب الأحيان.استخدم (Spotlight) بدلاً من أيقونات التطبيقات:أفضل طريقة لتنظيم التطبيق هي تجنبه تمامًا، حيث يمكنك العثور على أي تطبيق بسرعة وفعالية عن طريق كتابة الأحرف القليلة الأولى من اسمه في خانة البحث في (Spotlight). |
| 22,564 | 5 ميزات يتفوق بها تطبيق تلغرام على واتساب |
يعتبر تطبيق واتساب أحد أكثر تطبيقات المراسلة الفورية شعبيةً في العالم، حيث وصل عدد مستخدميه إلى أكثر من ملياري مستخدم حول العالم هذا العام، كما وصل عدد الرسائل المرسلة عبره إلى 65 مليار رسالة يوميًا، لذلك تستمر شركة واتساب في تقديم تحديثات وميزات جديدة للبقاء في صدارة المنافسة. وعلى الرغم من كل هذه الأرقام، إلا أن تطبيق تلغرام يعتبر منافسًا قويًا لواتساب حيث وصل عدد مستخدميه إلى أكثر من 400 مليون مستخدم شهريًا، ومن المتوقع أن يتضاعف هذا الرقم خلال السنوات القادمة، حيث تقدم الشركة العديد من الميزات الجديدة بصورة مستمرة لمنافسة لتطبيق واتساب. فيما يلي أهم 5 ميزات يتفوق بها تطبيق تلغرام على واتساب: 1- إمكانية تعديل الرسائل المرسلة: يمكنك تعديل الرسائل المرسلة داخل تطبيق تلغراممن خلال اتباع الخطوات التالية: 2- الإشعارات الذكية: 3- أذونات المجموعة: 4- إمكانية إرسال الرسائل بدون صوت: 5- المحادثات السرية الذاتية التدمير: تُحفظ كافة المحادثات السرية في هاتفك ولا تُرفع إلى خوادم تلغرام، وهذا يعني أنك فقط من يستطيع الوصول إليها في الجهاز التي اُنشئت فيه، وستختفي فور تسجيل الخروج أو حذف التطبيق. |
| 22,556 | التعامل مع الأخطاء، جرب... التقط try..catch في جافاسكربت |
مهما كنّا عباقرة نحن معشر المبرمجين، فلا بدّ أن تكون في السكربتات مشكلة ما. تحدث هذه المشاكل إمّا بسببنا، أو بسبب شيء أدخله المستخدم لم نتوقّعه، أو بسبب ردّ فيه خطأ من الخادوم، أو بمليار سبب آخر. في العادة ”يموت“ السكربت (أي يتوقّف مباشرة) لو حدث خطأ، ويطبع ذلك في الطرفية. ولكنّ الصياغة try..catch تتيح لنا ”التقاط“ هذه الأخطاء والقيام بما هو مفيد بدل أن يموت السكربت. صياغة try..catchللتعبير try..catch كتلتين برمجيتين أساسيتين: التجربة try والالتقاط catch بعدها: try { // الشيفرة... } catch (err) { // التعامل مع الأخطاء }يعمل التعبير هكذا:
بهذا لا تقتل الأخطاء داخل كتلة try {…} السكربت، فما زال ممكنًا أن نتعامل معها في catch. وقت الأمثلة.
تحذير: لا يعمل تعبير try..catch إلّا مع الأخطاء أثناء التشغيل يجب أن تكون الشيفرة البرمجية صياغتها صحيحة لكي تعمل try..catch بعبارة أخرى، يجب أن تكون الشيفرة البرمجية خالية من أخطاء الصياغة. لن تعمل في هذه الحالة لأن هنالك أقواسًا مفتوحة بدون غُلاقاتها. try { {{{{{{{{{{{{ } catch(e) { alert("لا يمكن للمحرك فهم هذه الشيفرة فهي غير صحيحة"); }أولًا يقرأ محرك جافاسكربت الشيفرة البرمجية، ومن ثمّ يشغّلها. تدعى الأخطاء التي تحدث في مرحلة القراءة أخطاء التحليل (parse-time) ولا يمكن إصلاحها (من داخل الشيفرة البرمجية نفسها). وذلك لأن محرك لغة جافاسكربت لا يستطيع فهم الشيفرة البرمجية من الأساس. تحذير:تعمل الصياغة try..catch بشكل متزامن. إذا حدث خطأ ما في شيفرة برمجية مجدولة مثلما في setTimeout فلن تستطيع الصياغة try..catch أن تلتقطه: try { setTimeout(function() { noSuchVariable; // السكربت سيموت هنا }, 1000); } catch (e) { alert( "won't work" ); }وذلك لأن التابِع سيُنفذ لاحقًا، بينما يكون محرك جافاسكربت غادر باني try..catch. للتقاط خطأ بداخل تابِع مُجدوَل يجب أن تكون الصياغة try..catch في داخل هذا التابِع. setTimeout(function() { try { // صياغة try..catch تُعالح الخطأ noSuchVariable; // try..catch handles the error! } catch { alert( "error is caught here!" ); } }, 1000); كائن الخطأ Errorتولّد جافاسكربت -متى حدث الخطأ- كائنًا يحوي تفاصيل الخطأ كاملةً، بعدها تُمرّرها وسيطًا إلى catch: try { // ... } catch(err) { // هذا ”كائن الخطأ“، ويمكننا استعمال أيّ اسم نريد بدل err // ... }لكائن الخطأ (في حالة الأخطاء المضمّنة في اللغة) خاصيتين اثنتين:
كما هناك خاصيات أخرى غير قياسية في أغلب بيئات جافاسكربت. أكثرها استعمالًا ودعمًا هي:
مثال: try { *!* lalala; // خطأ المتغيّر غير معرّف */!* } catch(err) { alert(err.name); // ReferenceError(خطأ في الإشارة) alert(err.message); // المتغيّر lalala غير معرف alert(err.stack); // ReferenceError:(خطأ في الإشارة) المتغيّر lalala غير معرّف في (...call stack) //يمكننا أيضًا عرض الخطأ بالكامل //تحول الخطأ إلى سلسلة نصية هكذا :"name: message" alert(err); // ReferenceError:(خطأ في الإشارة) المتغيّر lalala غير معرّف } إسناد "catch" الاختياريتحذير:هذه إضافة حديثة للغة من الممكن أن تحتاج لترقيع الخطأ في المتصفحات القديمة لأن هذه الميّزة جديدة. لو لم تريد تفاصيل الخطأ فيمكنك إزالتها من catch: try { // ... } catch { // <-- بدون المتغير (err) // ... } استعمال "try..catch"هيًا نرى معًا مثالًا واقعيًا عن try..catch: كما نعلم فجافاسكربت تدعم التابِع JSON.parse(str) ليقرأ القيم المرمّزة بِـ JSON. عادةً ما نستعمله لفكّ ترميز البيانات المستلمة من الشبكة، كانت آتية من خادوم أو من أيّ مصدر غيره. نستلم البيانات ونستدعي JSON.parse هكذا: let json = '{"name":"John", "age": 30}'; // بيانات من الخادوم // لاحظ let user = JSON.parse(json); // نحوّل التمثيل النصي إلى كائن جافاسكربت // الآن صار user كائنًا فيه خاصيات أتت من السلسلة النصية alert( user.name ); // John alert( user.age ); // 30يمكنك أن ترى تفاصيل أكثر عن JSON في درس JSON methods, toJSON. لو كانت سلسلة json معطوبة، فسيُولّد JSON.parse خطأً و”ويموت“ السكربت. هل نقبل بالأمر الواقع المرير؟ لا وألف لا! في هذا الحال لن يعرف الزائر ما يحدث لو حدث للبيانات أمر (ما لم يفتح طرفية المطوّرين). وعادةً ما لا يحب الناس ما ”يموت“ أمامهم دون أن يُعطيهم رسالة خطأ. فلنستعمل try..catch للتعامل مع هذه المعضلة: let json = "{ bad json }"; try { let user = JSON.parse(json); // <-- لو حدث خطأ... alert( user.name ); // فلن يعمل هذا } catch (e) { // ...تنتقل عملية التنفيذ إلى هنا alert( "Our apologies, the data has errors, we'll try to request it one more time." ); // المعذرة، في البيانات أخطاء. سنحاول طلبها مرة ثانية. alert( e.name ); alert( e.message ); }استعملنا هنا الكتلة catch لعرض رسالة لا أكثر، ولكن يمكن أن نستغلّها أفضل من هذا: مثل إرسال طلب إلى الشبكة، أو اقتراح عملية بديلة على الزائر أو إرسال معلومات الخطأ إلى … تسجيل، وغيرها… هذا كلّه أفضل من الموت والموت فقط. رمي أخطائنا نحنماذا لو كان كائن json صحيح صياغيًا إلّا أنّ الخاصية المطلوبة name ليست فيه؟ هكذا مثلًا: let json = '{ "age": 30 }'; // البيانات ناقصة try { let user = JSON.parse(json); // <-- لا أخطاء alert( user.name ); // ما من اسم! } catch (e) { alert( "doesn't execute" ); // لا يتنفّذ السطر }هنا سيعمل التابِع JSON.parse كما يجب، لكن عدم وجود الخاصية name هي المشكلة والخطأ في هذه الحالة. لتوحيد طريقة معالجة الأخطاء، سنستخدم مُعامل throw. مُعامل "الرمي" throwيُولّد لنا مُعامل الرمي throw خطأً. صياغته هي: throw <error object>يمكننا تقنيًا استعمال ما نريد ليكون كائن خطأ، مثل الأنواع الأولية كالأعداد والسلاسل النصية. ولكن من الأفضل استعمال الكائنات ومن الأفضل أكثر أن تملك خاصيتي الاسم name والرسالة message (لتكون متوافقة إلى حدٍّ ما مع الأخطاء المضمّنة). في جافاسكربت مختلف البانيات المضمّنة للأخطاء القياسية: الخطأ Error والخطأ الصياغي SyntaxError والخطأ في الإشارة ReferenceError والخطأ في النوع TypeError وغيرها. يمكننا استعمال هذه البانيات أيضًا لإنشاء كائنات الخطأ. صياغتها هي: let error = new Error(message); // أو let error = new SyntaxError(message); let error = new ReferenceError(message); // ...في الأخطاء المضمّنة في اللغة (ولا أعني الكائنات أيًا كانت، الأخطاء بعينها) تكون قيمة الخاصية name هي ذاتها اسم الباني، وتُؤخذ الرسالة message من الوسيط. مثال: let error = new Error("Things happen o_O"); // غرائب وعجائب ة_ه alert(error.name); // خطأ alert(error.message); // غرائب وعجائب ة_هلنرى نوع الخطأ الذي يُولّده التابِع JSON.parse: try { JSON.parse("{ bad json o_O }"); // جيسون شقي ة_ه } catch(e) { alert(e.name); // SyntaxError خطأ صياغي alert(e.message); // Unexpected token o in JSON at position 2 }كما رأينا فهو خطأ صياغي SyntaxError. وفي حالتنا نحن فعدم وجود الخاصية name هي خطأ، إذ لا بدّ أن يكون للمستخدم اسمًا. هيًا نرمِ الخطأ: let json = '{ "age": 30 }'; // البيانات ناقصة try { let user = JSON.parse(json); // <-- لا أخطاء if (!user.name) { throw new SyntaxError("Incomplete data: no name"); // (*) البيانات ناقصة: ليس هنالك اسم } alert( user.name ); } catch(e) { alert( "JSON Error: " + e.message ); // خطأ JSON: البيانات ناقصة: ليس هنالك اسم }يُولّد مُعامل throw (في السطر (*)) خطأً صياغيًا SyntaxError له الرسالة الممرّرة message، تمامًا كما تُولّد جافاسكربت نفسها الخطأ. بهذا يتوقّف التنفيذ داخل try وينتقل سير العملية إلى catch. الآن صارت الكتلة catch هي المكان الذي نتعامل فيه مع الأخطاء فحسب، أكانت أخطاء JSON.parse أم أخطاء أخرى. إعادة الرمييمكننا في المثال أعلاه استعمال try..catch للتعامل مع البيانات الخاطئة. ولكن هل يمكن أن يحدث خطأ آخر غير متوقّع في كتلة try {...}؟ مثلًا لو كان خطأ المبرمج (لم يعرّف المتغير) أو شيئًا آخر ليس أنّ ”البيانات خاطئة“؟ مثال: let json = '{ "age": 30 }'; // البيانات ناقصة try { user = JSON.parse(json); // نسينا ”let“ قبل user // ... } catch(err) { alert("JSON Error: " + err); // خطأ JSON: خطأ في الإشارة: user غير معرّف (في الواقع، ليس خطأ JSON) }كلّ شيء ممكن كما تعلم! فالمبرمجون يخطؤون. حتّى في الأدوات مفتوحة المصدر والتي يستعملها ملايين البشر لسنين تمضي، لو اكتُشفت علة فجأةً ستؤدّي إلى اختراقات مأساوية. في حالتنا هذه على try..catch التقاط أخطاء ”البيانات الخاطئة“ فقط، ولكنّ طبيعة catch هي أن تلتقط كلّ الأخطاء من try. فهنا مثلًا التقطت خطأً غير متوقع ولكنها ما زالت تصرّ على رسالة "JSON Error". هذا ليس صحيحًا ويصعّب من تنقيح الشيفرة كثيرًا. لحسن الحظ فيمكننا معرفة الخطأ الذي التقطناه، من اسمه name مثلًا: try { user = { /*...*/ }; } catch(e) { alert(e.name); // ”خطأ في الإشارة” محاولة الوصول لمتغيّر غير معرّف }القاعدة ليست بالمعقّدة: على catch التعامل مع الأخطاء التي تعرفها فقط، و”إعادة رمي“ ما دونها. يمكننا توضيح فكرة ”إعادة الرمي“ بهذه الخطوات:
في الشيفرة أسفله استعملنا إعادة الرمي لتتعامل الكتلة catch مع أخطاء الصياغة فقط SyntaxError: let json = '{ "age": 30 }'; // البيانات ناقصة try { let user = JSON.parse(json); if (!user.name) { throw new SyntaxError("Incomplete data: no name"); // البيانات ناقصة: لا اسم } blabla(); // خطأ غير متوقع alert( user.name ); } catch(e) { if (e.name == "SyntaxError") { alert( "JSON Error: " + e.message ); // خطأ JSON: كذا كذا } else { throw e; // نُعيد رميه (*) } }الخطأ المرمي في السطر (*) داخل كتلة catch ”يسقط خارج أرض“ try..catch ويمكننا إمّا التقاطه باستعمال تعبير try..catch خارجي (لو كتبناه) أو سيقتل الخطأ السكربت. هكذا لا تتعامل الكتلة catch إلا مع ما تعرف مع أخطاء وتتخطّى (إن صحّ القول) الباقي. يوضّح المثال أسفله كيفية التقاط هذه الأخطاء بمستويات أخرى من try..catch: function readData() { let json = '{ "age": 30 }'; try { // ... blabla(); // خطأ! } catch (e) { // ... if (e.name != 'SyntaxError') { throw e; // نُعيد رميه (لا ندري طريقة التعامل معه) } } } try { readData(); } catch (e) { alert( "External catch got: " + e ); // التقطناه أخيرًا! }هكذا لا تعرف الدالة readData إلّا طريقة التعامل مع أخطاء الصياغة SyntaxError، بينما تتصرّف تعابير try..catch الخارجية بغيرها من أخطاء (إن عرفتها). try..catch..finallyلحظة… لم ننتهي بعد. يمكن أيضًا أن يحتوي تعبير try..catch على مُنغلقة أخرى: finally. لو كتبناها فستعمل في كلّ الحالات الممكنة:
هكذا هي الصياغة ”الموسّعة“: try { ... نحاول تنفيذ الشيفرة ... } catch(e) { ... نتعامل مع الأخطاء ... } finally { ... ننفّذه مهما كان الحال ... }جرّب تشغيل هذه الشيفرة: try { alert( 'try' ); if (confirm('Make an error?')) BAD_CODE(); // أتريد ارتكاب خطأ؟ } catch (e) { alert( 'catch' ); // أمسكناه } finally { alert( 'finally' ); // بعد ذلك }يمكن أن تعمل الشيفرة بطريقتين اثنتين:
نستعمل عادةً مُنغلقة finally متى ما شرعنا في شيء وأردنا إنهائه مهما كانت نتيجة الشيفرة. فمثلًا نريد قياس الوقت الذي تأخذه دالة أعداد فيبوناتشي fib(n). الطبيعي أن نبدأ القياس قبل التشغيل ونُنهيه بعده، ولكن ماذا لو حدث خطأ أثناء استدعاء الدالة؟ مثلًا خُذ شيفرة الدالة fib(n) أسفله وسترى أنّها تُعيد خطأً لو كانت الأعداد سالبة أو لم تكن أعدادًا صحيحة (not integer). مُنغلقة finally هي المكان الأمثل لإنهاء هذا القياس مهما كانت النتيجة، فتضمن لنا بأنّ الوقت سيُقاس كما ينبغي في الحالتين معًا، نجح تنفيذ أم لم ينجح وأدّى لخطأ: let num = +prompt("Enter a positive integer number?", 35) let diff, result; function fib(n) { if (n < 0 || Math.trunc(n) != n) { throw new Error("Must not be negative, and also an integer."); } return n <= 1 ? n : fib(n - 1) + fib(n - 2); } let start = Date.now(); try { result = fib(num); } catch (e) { result = 0; *!* } finally { diff = Date.now() - start; } */!* alert(result || "error occurred"); alert( `execution took ${diff}ms` );يمكنك التأكّد بتشغيل الشيفرة وإدخال 35 في prompt، وستعمل كما يجب، أي تكون finally بعد try. وبعد ذلك جرّب إدخال -1 وسترى خطأً مباشرةً وسيأخذ تنفيذ الشيفرة مدّة 0ms، وكِلا الزمنين المقيسين صحيحين. أي أنّه يمكن للدالة أن بعبارة return أو throw، لا مشكلة إذ ستُنفّذ مُنغلقة finally في أيّ من الحالتين. ملاحظة:المتغيّرات في صياغة try..catch..finally محلية. لاحظ أن المتغيرات result و diff في الشيفرة البرمجية أعلاه معرّفة قبل الصياغة try..catch. وبذلك إذا عرفنا let في الصياغة try فستبقى مرئية بداخلها فقط. ملاحظة: بخصوص finally و return فإن مُنغلقة finally تعمل مع أي خروج من صياغة try..catch والتي تتضمن خروج واضح من خلال تعليمة return. في المثال أدناه هنالك تعليمة return في try في هذه الحالة ستنفذّ finally قبل عودة عنصر التحكم إلى الشيفرة البرمجية الخارجية مباشرة. function func() { try { *!* return 1; */!* } catch (e) { /* ... */ } finally { *!* alert( 'finally' ); */!* } } alert( func() ); // أولًا ستعمل تعليمة alert من المنغلقة finally ومن ثمّ هذهملاحظة: إن باني try..finally بدون منغلقة catch مفيد أيضًا إذ يمكننا استخدامه عندما لا نريد معالجة الأخطاء وإنما نريد التأكد من أن العمليات التي بدأناها انتهت فعلًا. function func() { // نبدأ بشيء يحتاج لإكمال (مثل عملية القياس) try { // ... } finally { // نكمله هنا حتى وإن كلّ السكربت مات } }في الشيفرة البرمجية أعلاه، هنالك خطأ دائمًا يحدث في try لأنه لا يوجد catch. ومع ذلك ستعمل finally قبل الخروج من التابع. الالتقاط العموميتحذير: مخصص لبيئة العمل إن المعلومات في هذه الفقرة ليست جزءًا من لغة جافاسكربت لنقل مثلًا أنْ حصل خطأ فادح خارج تعبير try..catch، ومات السكربت (مثلًا كان خطأ المبرمج أو أيّ شيء آخر مريب). أهناك طريقة يمكننا التصرّف فيها في هكذا حالات؟ لربّما أردنا تسجيل الخطأ أو عرض شيء معيّن على المستخدم (عادةً لا يرى المستخدمون رسائل الأخطاء) أو غيرها. لا نجد في المواصفة أيّ شيء عن هذا، إلّا أنّ بيئات اللغة تقدّم هذه الميزة لأهميتها البالغة. فمثلًا تقدّم Node.js الحدث process.on("uncaughtException"). ولو كنّا نُطوّر للمتصفّح فيمكننا إسناد دالة إلى خاصية window.onerror الفريدة (إذ تعمل متى حدث خطأ لم يُلتقط). الصياغة هي: window.onerror = function(message, url, line, col, error) { // ... };
مثال: <script> window.onerror = function(message, url, line, col, error) { alert(`${message}\n At ${line}:${col} of ${url}`); }; function readData() { badFunc(); // Whoops, something went wrong! } readData(); </script>عادةً، لا يكون الهدف من …. العمومي window.onerror استعادة تنفيذ السكربت (إذ هو أمر مستحيل لو كانت أخطاء من المبرمج) بل يكون لإرسال هذه الرسائل إلى المبرمج. كما أنّ هناك خدمات على الوِب تقدّم مزايا لتسجيل الأخطاء في مثل هذه الحالات، أمثال https://errorception.com وhttp://www.muscula.com. وهكذا تعمل:
يتيح لنا تعبير try..catch التعامل مع الأخطاء أثناء تنفيذ الشيفرات. كما يدلّ اسمها فهي تسمح ”بتجربة“ تنفيذ الشيفرة و”والتقاط“ الأخطاء التي قد تحدث فيها. صياغتها هي: try { // شغّل الشيفرة } catch(err) { // انتقل إلى هنا لو حدث خطأ // err هو كائن الخطأ } finally { // مهما كان الذي حدث، نفّذ هذا }يمكننا إزالة قسم catch أو قسم finally، واستعمال الصيغ الأقصر try..catch وtry..finally. لكائنات الأخطاء الخاصيات الآتية:
لو لم تُرد كائن الخطأ فيمكنك إزالتها باستعمال catch { بدل catch(err) {. يمكننا أيضًا توليد الأخطاء التي نريد باستعمال مُعامل throw. تقنيًا يمكن أن يكون وسيط throw ما تريد ولكن من الأفضل لو كان كائن خطأ يرث صنف الأخطاء Error المضمّن في اللغة. سنعرف المزيد عن توسعة الأخطاء في القسم التالي. كما يُعدّ نمط ”إعادة الرمي“ البرمجي نمطًا مهمًا عند التعامل مع الأخطاء، فلا تتوقّع كتلة catch إلّا أنواع الأخطاء التي تفهمها وتعرف طريقة التعامل معها، والباقي عليها إعادة رميه لو لم تفهمه. حتّى لو لم نستعمل تعبير try..catch فأغلب البيئات تتيح لنا إعداد … أخطاء ”عمومي“ لالتقاط الأخطاء التي ”تسقط أرضًا“. هذا … في المتصفّحات اسمه window.onerror. تمارين أخيرًا أم الشيفرة؟الأهمية: 5 وازِن بين الشيفرتين هتين.
هل هنالك ميزة إضافية لاستخدام finally؟ أم أن الشيفرتين السابقتين متساويتين؟ إن كان هنالك ميزّة اكتب مثلًا يوضحها. الحلعندما ننظر إلى الشيفرة الموجودة بداخل التابع يصبح الفرق جليًا. يختلف السلوك إذا كان هناك "قفزة" من "try..catch". على سبيل المثال، عندما يكون هناك تعليمة return بداخل صياغة try..catch. تعمل منغلقة finally في حالة وجود أي خروج من صياغة try..catch، حتى عبر تعليمة return: مباشرة بعد الانتهاء من try..catch ، ولكن قبل أن تحصل شيفرة الاستدعاء على التحكم. function f() { try { alert('start'); return "result"; } catch (e) { /// ... } finally { alert('cleanup!'); } } f(); // cleanup!… أو عندما يكون هناك throw، مثل هنا: function f() { try { alert('start'); throw new Error("an error"); } catch (e) { // ... if("can't handle the error") { throw e; } } finally { alert('cleanup!') } } f(); // cleanup!تضمنُ finally عملية التنظيف هنا. إذا وضعنا الشيفرة البرمجية في نهاية f ، فلن تشغّل في هذا السيناريو. ترجمة -وبتصرف- للفصل Error handling, "try..catch" من كتاب The JavaScript language |
| 22,548 | مع هذا التطبيق احصل على تصميم iOS في لوحة الإعدادات السريعة على أندرويد |
مع هذا التطبيق احصل على تصميم iOS في لوحة الإعدادات السريعة على أندرويد
لاشك في أن نظام أندرويد أكثر وظيفيًا من iOS عندما يتعلق الأمر بالإشعارات وكذلك التخصيص، ومع ذلك، علينا جميعًا بأن نعترف بوجود أناقة مصقولة في لوحة نظام آبل ومركز تحكمها في أجهزتها، لذلك قد يفضل بعض المستخدمين التصميم الشفاف والإشعارات المنفصلة وصفحات التبديل السريعة، فإذا كنت واحدًا من هؤلاء، أو مهتمًا بتجربة تصميم iOS على جهاز أندرويد ، فقد يستحق تطبيق Mi Control Center الجديد نظرة. وباختصار، يمكن تعريفه بأنه عبارة عن تطبيق يمنح إشعاراتك ولوحة إعداداتك السريعة تحولًا على غرار iOS / MIUI، بما في ذلك بعض الرسوم المتحركة الأنيقة التي تجعل التمرير لأسفل والوصول إلى كل هذا أكثر متعة. مع هذا التطبيق احصل على تصميم iOS في لوحة الإعدادات السريعة على أندرويدوما هو قادر عليه تطبيق Mi Control Center على سبيل المثال، فصل مركز الإشعارات والإعدادات السريعة إلى لوحتين يمكن سحبهما لأعلى عن طريق التمرير على نصفين مختلفين من الشاشة، أو يمكن تخصيص العملية لإظهار التبديل السريع أعلى مركز الإشعارات تمامًا مثل أندرويد الخام، كما وهناك الكثير من التخصيصات التي يمكنك إجرائها، مثل تعيين صورة كخلفية للوحتين أو تغيير شكل إعدادات الإعدادات السريعة. مع هذا التطبيق احصل على تصميم iOS في لوحة الإعدادات السريعة على أندرويدأخيرًا، لم يكن أندرويد و iOS أكثر قربًا من حيث الميزات والجماليات، مما سيُساعد تطبيق Mi Control Center على الأقل، بجعل الفجوة أصغر، في الختام، التطبيق متوفّر للتحميل مجّانًا على متجر جوجل بلاي، مع وجود بعض المميزات المتقدمة التي تحتاج للشراء. تحميل تطبيق Mi Control Center على متجر جوجل بلاي. التدوينة مع هذا التطبيق احصل على تصميم iOS في لوحة الإعدادات السريعة على أندرويد ظهرت أولاً على عالم التقنية. |