مقدمة: لماذا Swift يعض حتى لو كنت تحبه
\n\nقررت أن تصبح مطور iOS. قمت بتثبيت Xcode، وكتبت أول "Hello, World!" - وشعرت وكأنك تيم كوك تقريبًا. ثم بدأ الأمر: Xcode يوبخك بسبب nil غير مفهوم، الكود لا يُترجم، والتطبيق يتعطل عند أول ضغطة زر. مألوف؟
مرحبًا بك في عالم Swift - اللغة التي تُحب لأمانها، ولكن تُكره لصرامتها. في هذه المقالة، سنستعرض أخطاء تعلم Swift التي يرتكبها 90% من المبتدئين. ستتعلم كيفية تجنبها، وتوفير أعصابك، والتوقف عن لعن Apple. هيا بنا!
\n\nالخطأ رقم 1: تجاهل Optional والتعامل مع nil "على عاتقك"
\n\nSwift هي أول لغة حيث nil ليس مجرد "فارغ"، بل فلسفة كاملة. يحاول المبتدئون غالبًا التعامل مع Optionals كما في Python أو JavaScript: "ربما هناك شيء، وربما لا". ويحصلون على تعطل.
كيف يبدو هذا في الكود
\n\n// ❌ خطأ نموذجي للمبتدئين\nvar userName: String? = nil\nprint("مرحبًا، \\(userName.uppercased())!") // خطأ فادح: تم العثور على nil بشكل غير متوقع\n\n\nهنا userName هو Optional (String?). لقد نسيت التحقق مما إذا كان يحتوي على قيمة، وحاولت استدعاء الدالة uppercased() على nil. يتعطل التطبيق.
الطريقة الصحيحة
\n\n// ✅ استخراج آمن\nif let safeName = userName {\n print("مرحبًا، \\(safeName.uppercased())!")\n} else {\n print("الاسم غير محدد")\n}\n\n// أو باستخدام guard\nguard let unwrappedName = userName else {\n print("خطأ: الاسم مفقود")\n return\n}\nprint("مرحبًا، \\(unwrappedName.uppercased())!")\n\n\nنصيحة: فكر دائمًا: "هل يمكن أن يكون هذا المتغير nil؟". إذا كان الأمر كذلك، استخدم if let أو guard let. هذا واحد من أكثر أخطاء المبتدئين في Swift شيوعًا، والذي يضيع وقتًا في التصحيح.
الخطأ رقم 2: الخوف من Closures واستخدام @escaping
\n\nClosures في Swift تشبه الدوال المجهولة. يخافها المبتدئون، ويكتبون دوالًا ضخمة بدلاً من Closures المدمجة، ثم يتساءلون لماذا الكود غير قابل للقراءة. وعندما يتعلق الأمر بالتزامن غير المتزامن، يبدأ الجحيم مع @escaping.
مثال على الخوف من Closures
\n\n// ❌ كود يمكن تقصيره 3 مرات\nfunc fetchData(completion: (String) -> Void) {\n let result = "تم تحميل البيانات"\n completion(result)\n}\n\n// الاستدعاء\nfetchData { data in\n print(data)\n}\n\n\nكل شيء جميل؟ نعم. لكن المبتدئين يكتبون هكذا:
\n\n// ❌ أسلوب سيء\nfunc fetchData() {\n let result = "تم تحميل البيانات"\n handleResult(result: result)\n}\n\nfunc handleResult(result: String) {\n print(result)\n}\n\n\nوعند الحاجة إلى طلب غير متزامن، ينسون @escaping:
// ❌ خطأ: Closure ليست escaping\nfunc loadUser(id: Int, completion: (User) -> Void) {\n DispatchQueue.global().async {\n let user = User(id: id)\n completion(user) // خطأ في الترجمة!\n }\n}\n\n\nسيقول Xcode: "يجب أن يكون Closure من نوع @escaping". نصلح:
// ✅ بشكل صحيح\nfunc loadUser(id: Int, completion: @escaping (User) -> Void) {\n DispatchQueue.global().async {\n let user = User(id: id)\n completion(user)\n }\n}\n\n\nالخلاصة: لا تخف من Closures. إنها أصدقاؤك. و @escaping هو مجرد علامة تقول: "سيتم استدعاء هذا Closure لاحقًا، احفظه". تذكر هذا - وسيختفي نصف أخطاء Swift للمبتدئين.
الخطأ رقم 3: الخلط بين الفئات (Classes) والهياكل (Structs)
\n\nفي Swift، هناك فئات (نوع مرجعي) وهياكل (نوع قيمي). غالبًا ما يستخدم المبتدئون الفئات في كل مكان لأنهم "اعتادوا عليها من لغة أخرى