مساحة اعلانية

آخر المواضيع

مقدمة عن swift : القسم 2


مقدمة عن swift: القسم 2
مقدمة عن swift: القسم 2



في اول مقالة من هذه السلسلة عن swift, تحدثنا عن فلسفة swift, القينا نظرة أولى عن تركيبة الكود فيها, و ركزنا على الاختلافات الأساسية بين swift و بين Objective-C. في هذا الدرس, سنتابع بحثنا عن تركيبة كود swift. ستتعلم أيضا عن الاختيارات و سنرى كيفية عمل إدارة الذاكرة في swift.




1. الشرط و العقد IF



اذا كان التصريح متطابقا في swift و Objective-C. باستثناء اختلافين بسيطين:
  •     تعد الاقواس الهلالية حول متغير الشرط اختيارية
  •     الاقواس المعوجة مطلوبة

هذه هي الاختلافات الوحيدة مع تصريحات if في  Objective-C.

التسلسلات

كما راينا في الدرس السابق, يتضمن swift عاملين متسلسلين ..< و ... لتحديد قيم متسلسلة. يعد هذان العاملان عامل ذات سلسلة نصف مغلقة و عامل ذات سلسلة مغلقة.

تمثل السلسلة النصف المغلقة, مثل 1..<5, القيم 1, 2, 3, و 4, باستثناء 5. تمثل السلسلة المغلقة, مثل 1...5, القيم values 1, 2, 3, 4, و تتضمن 5.

تستخدم السلاسل في العقد, اشتراك المصفوفات, و حتى في تصريحات swift. الق نظرة على هذه الأمثلة التالية.

      
// for loop example

for i in 1..<10 {

   

}

// iterates from 1 to 9

      

// array subscript example

let someArray = ["apple","pair","peach","watermelon","strawberry"]

for fruit in someArray[2..<4] {

    println(fruit)

}

// outputs: peach and watermelon

      

// switch example

switch someInt {

    case 0:

    // do something with 0

    case 1..<5:

    // do something with 1,2,3,4

    case 5...10:

    // do something with 5,6,7,8,9,10

    default:

    // everything else

}

Switch

تعد تصريحات swift اكثر قوة في swift من Objective-C. في Objective-C, تحتاج نتيجة تعبير تصريحاتswift  الى ان تكون من نوع رقم و يجب ان تكون قيم كل تصريح  ثابت أو تعبير ثابت. لا يعد ذلك صحيحا في swift. في swift, يمكن للتصريحات ان تكون من أي نوع, بما في ذلك التسلسلات.

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

ها هو مثال عن تصريح switch بأصناف String:

      
let vegetable = "red pepper"

switch vegetable {

case "celery":

    let vegetableComment = "Add some raisins and make ants on a log."

case "cucumber", "watercress":

    let vegetableComment = "That would make a good tea sandwich."

default:

    let vegetableComment = "Everything tastes good in soup."

}

في swift, لا تقع تصريحات الصنف بشكل نموذجي. يعد هذا قرارا تصميميا مدروسا لتجنب الأخطاء الشائعة. في حال احتاج صنف محدد للوقوع, بامكانك استخدام الكلمة الاساسية fallthrough للدلالة على المجمع.
switch someInt {

    case 0:

    // do something with 0

    case 1:

    // do something with 1

    case 2:

    // do something with 2

        fallthrough

    default:

    //do something for everything else

}



// case 2 will fall through to default case

لا نقف عند هذا فحسب. يضيف swift ميزتين الى switch, روابط القيم و جمل where. يستخدم رابط القيم مع الكمات الأساسية case let لربط ثابت مع نوع متماثل. تضيف جمل where شرطا إضافيا لتصريح الصنف باستخدام الكلمة الأساسية where.

ستفهم هذان المفهومان من خلال الأمثلة. يعرض تكتل الكود التالي كيفية عمل روابط القيم.

 

let somePoint = (xaxis:2, yaxis:0)

switch somePoint {

case (let x, 0):

    println("on the x-axis with an x value of \(x)")

case (0, let y):

    println("on the y-axis with a y value of \(y)")

case let (x, y):

    println("somewhere else at (\(x), \(y))")

}

تصريح الصنف الأول, الصنف (let x, 0), سترتبط بالقيم حيث yaxis تساوي 0 و اية قيمة لـ xaxis, و سنربط xaxis بالثابت x لتستخدم داخل تصريح الصنف.

ها هو مثال عن جملة where.

      
let vegetable = "red pepper"

switch vegetable {

case "celery":

    println("Add some raisins and make ants on a log.")

case let x where x.hasSuffix("pepper"):

    println("I'm allergic to \(x)")

default:

    println( "Everything tastes good in soup.")

}



// outputs: I'm allergic to red pepper

2. Functions and Closures

الدوال

يعد تعريف الدوال و الانغلاقات سهلا في swift. يعلم مطورو Objective-C هذان بشكل افضل كالدوال و التكتلات.



في swift, يمكن لمعاملات الدوال ان يكون لديها قيم افتراضية, التي تذكرك اللغات المكتوبة, مثل PHP و Ruby.

تعد تركيبة كود الدوال كتالي:

      
func functionName(parameterName: Type = DefaultValue) -> returnType {

    [...]

    return returnType;

}

من اجل كتابة دالة sayHello تأخذ اسم معاملة من نوع string و تعود بـ Bool اذا نجحت, سنكتب التالي:
func sayHello(name: String) -> Bool {

    println("hello \(name)");

    return true;

}



sayHello("World")

// output

// hello World

لتمرير قيمة افتراضية من اجل اسم المعاملة, سيكون انشاء الدالة كالتالي:

      
func sayHello(name: String = "World") -> Bool {

    println("hello \(name)");

    return true;

}



sayHello()

// output

// hello World



sayHello("mike")

// output

// hello mike

تعد tuples ميزة غائبة تماما في Objective-C. في swift, يمكن للدوال ان تعود بقيم متعددة على شكل tuple. تعامل tuples كمتغير فردي, مما يعني انه يمكنك تمرريها تماما كالمتغير.

تعد tuples سهلة الاستخدام. في الحقيقة, لقد عملنا مسبقا مع tuples في الدرس السابق عندما عددنا القاموس. في مقطع الكود التالي, يعد زوج القيمة/المفتاح tuple.
for (key,value) in someDictionary {

    println("Key \(key) has value \(value)"

}

كيف تستخدم tuples و كيف تستفيد منهم؟ دعونا نلقي نظرة على مثال اخر. دعونا نعدل دالة sayHello لتعيد قيمة منطقية عند النجاح بالإضافة الى الرسالة الناتجة. سنقوم بذلك من خلال إعادة tuple, (Bool, String). ستبدو دالة sayHello المحدثة كالتالي:

      
func sayHello(name: String = "World") -> (Bool, String) {

    let greeting = "hello \(name)"

    return (true, greeting);

}



let (success, greeting) = sayHello()

println("sayHello returned success:\(success) with greeting: \(greeting)");

// output

// sayHello returned success:1 with greeting: hello World

لقد كانت tuples على قائمة امنيات مبرمجي  Objective-C لمدة طويلة.

احدى ميزات tuples الجيدة هي انه يمكننا تسمية متغيرات الرجوع. اذا عدنا للمثال السابق و اعطينا أسماء لمتغيري tuple, سنحصل على التالي:

      
func sayHello(name: String = "World") -> (success: Bool, greeting: String) {

    let greeting = "hello \(name)"

    return (true, greeting);

}



let status = sayHello()

println("sayHello returned success:\(status.success) with greeting: \(status.greeting)");

// output

// sayHello returned success:1 with greeting: hello World

هذا يعني انه بدلا من تعريف ثابت منفصل لكل عنصر عائد من tuple, يمكننا الولوج الى عناصر tuple العائدة باستخدام اشعار النقطة كما هو موضح في المثال السابق, status.success و status.greeting.

الانغلاقات

تعد في swift نفس التكتلات في Objective-C. يمكن تعريفهم داخل الخط, يمررون كالعوامل, أو يعودون بدوال. سنستخدمهم تماما كما كنا سنستخدم التكتلات في Objective-C.

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

تعد الانغلاقات من نوع الصنف الأول, مما يعني انه يمكن تمررها و الإعادة من قبل الدوال تماما كأي نوع اخر,  مثل Int , String , Bool, الخ. تعد الانغلاقات تكتلات من الكود الأساسية التي تستعدى لاحقا و لديهم وصول الى المجال الذي يعرفون به.

يعد انشاء اغلاق بلا اسم بسيطا كلف تكتل من الكوود بقوسين معوجين. يعد نوع الارجاع و المعاملات للانغلاقات منفصلة عن جسد الانغلاق في الكلمة الأساسية in.

دعونا نقول اننا نرغب بتعريف الاغلاق الذي يعود صحيحا اذا كان الرقم مساويا, ثم سيبدو شكل الانغلاق كالتالي:

      
let isEven = {

(number: Int) -> Bool in

let mod = number % 2

return (mod==0)

}

يأخذ انغلاق isEven Int كمعاملتها المفردة و تعود بـ Bool. يعد نوع الانغلاق هذا (number: Int) -> Bool, or (Int -> Bool) بشكل مختصر. يمكننا ان نستدعي isEven في أي مكان في الكود تماما كما يمكننا استدعاء تكتل الكود في Objective-C.

لتمرير انغلاق من هذا النوع كمعاملة دالة, سنستخدم نوع الانغلاق في تعريف الدالة:

      
let isEven = {

    (number: Int) -> Bool in

    let mod = number % 2;

    return (mod==0);

}



func verifyIfEven(number: Int, verifier:(Int->Bool)) ->Bool {

    return verifier(number);

}



verifyIfEven(12, isEven);

// returns true



verifyIfEven(19, isEven);

// returns false

في المثال السابق, تعد معاملة المحقق لدالة verifyIfEven اغلاقا يمكننا ان نمرره الى الدالة.

3. الأصناف و البنى

الاصناف

حان الوقت للتحدث عن حجر أساس البرمجة كائنية التوجه, الأصناف. تعرف الأصناف, كما ذكرت سابقا, بملف انشاء واحد بـ .swift extension. يتم تعريف تصريحات الخواص و الطرق في ذلك الملف أيضا.

نقوم بانشاء الأصناف بكلمة الصنف الأساسية المتبوعة باسم الصنف. يلف انشاء الصنف بقوسين معوجين. كما هو الحال في Objective-C, التسمية المعترف عليها للاصناف هي استخدام  camel case العليا لاسماء الأصناف.
class Hotel {

    //properties

    //functions

}

لانشاء نموذج لصنف Hotel نقوم بكتابة:
let h = Hotel()

في swift, ليس هنالك حاجة لاستدعاء init على الكائنات ذلك لان init تستدعى بشكل أوتوماتيكي.


يتبع ارث الصنف نفس النمط في Objective-C , تفصل النقطتان بين اسم الصنف و صنفها الفرعي. في المثال التاي, يرث Hotel من صنف BigHotel.     
class BigHotel: Hotel {

}

كما هو الحال Objective-C, فاننا نستخدم النقط للولوج الى حواص الكائن. ولكن يستخدم Swift أيضا النقط لاستدعاء الصنف و طرق النماذج كما يمكنك ان ترى اسفلا.

      
// Objective-C

UIView* view = [[UIView alloc] init];

[self.view addSubview:view];



// Swift

let view = UIView()

self.view.addSubview(view)

Properties

هنالك اختلاف اخر بين Swift و Objective-C و هو ان swift لا يميز بين متغيرات النموذج Objective-C و الخواص. يعد متغير النموذج خاصية.

يعد الإعلان عن خاصية تماما كتعريف متغير او ثابت, باستخدام الكمات الأساسية var و let. يكمن الاختلاف الوحيد في المجال الذي يتم به تعريفهما, أي مجال الصنف.
      

class Hotel {

    let rooms = 10

    var fullRooms = 0

}

في المثال السابق, تعد rooms قيمة غير متغيرة, ثابتة, تعين لـ 10 و تعد fullRooms كمتغير مع القيمة الأولية 0, التي يمكننا تغييرها لاحقا. القاعدة تقول بان الخواص تحتاج الى ان يتم بدأها عندما تعلن. الاستثناء الوحيد لهذه القاعدة هو optionals (الخيارات) التي سنناقشها في غضون ثوان.

الخواص المحسوبة

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

في الأسفل يوجد مثال عن الخواص المحسوبة. قمت بتغيير خاصية rooms الى var لاخر الأمثلة الثلاث. ستكتشف لماذا ذلك لاحقا.

      
class Hotel {

    var rooms = 10

    var fullRooms = 0

    var description: String {

        get {

            return "Size of Hotel: \(rooms) rooms capacity:\(fullRooms)/\(rooms)"

        }

    }

}

لان خاصية الوصف تقرأ-فقط و لديها تصريح عائد, يمكننا حذف الكلمة الأساسية get و الاقواس المعوجة, و تحفظ فقط تصريح عائد. يعد هذا اختصار و هذا ما سأستخدمه لبقة هذا الدرس.
      

class Hotel {

    var rooms = 10

    var fullRooms = 0

    var description: String {

        return "Size of Hotel: \(rooms) rooms capacity:\(fullRooms)/\(rooms)"

    }  

}

يمكننا تعريف الخواص المحسوبة المكتوبة-المقروءة. في صنف Hotel, نرغب بخاصية emptyRooms التي تحصل على عدد من الغرف الفارغة في الفندق, و لكننا نرغب أيضا بتحديث fullRooms عندما نعين الخاصية المحسوبة emptyRooms. يمكننا فعل ذلك باستخدام الكلمة الأساسية set كما هو مبين اسفلا.

      
class Hotel {

    var rooms = 10

    var fullRooms = 0

    var description: String {

        return "Size of Hotel: \(rooms) rooms capacity:\(fullRooms)/\(rooms)"

    }  

    var emptyRooms :Int {

        get {

            return rooms - fullRooms

        }

        set {

            // newValue constant is available here

            // containing the passed value

            if(newValue < rooms) {

                fullRooms = rooms - newValue

            } else {

                fullRooms = rooms

            }

        }

    }

}



let h = Hotel()

h.emptyRooms = 3

h.description

// Size of Hotel: 10 rooms capacity:7/10

في معين emptyRooms, يتم تسليم الثابت newValue لنا و يمثل القيمة التي تم تمريرها للمعين. من الضروري أيضا ملاحظة ان الخواص المحسوبة يتم الإعلان عنها دائما كمتغيرات, باستخدام الكلمة الأساسية var, ذلك لان قيمهم المحسوبة يمكنها ان تتغير.

الطرق

لقد قمنا مسبقا بتغطية الدوال في هذا الدرس. تعد الطرق لا شيء اكثر من دوال مرتبطة بنوع, كالصنف. في المثال التالي سنقوم بانشاء طريقة النموذج, bookNumberOfRooms, في صنف Hotelالذي أنشأناه مسبقا.

      
class Hotel {

    var rooms = 10

    var fullRooms = 0

    var description: String {

        return "Size of Hotel: \(rooms) rooms capacity:\(fullRooms)/\(rooms)"

    }

    var emptyRooms :Int {

        get {

            return rooms - fullRooms

        }

        set {

            // newValue constant is available here

            // containing the passed value

            if(newValue < rooms) {

                fullRooms = rooms - newValue

            } else {

                fullRooms = rooms

            }

        }



    }

    func bookNumberOfRooms(room:Int = 1) -> Bool

    {

        if(self.emptyRooms>room) {

            self.fullRooms++;

            return true

        } else {

            return false

        }

    }

}



let h = Hotel()

h.emptyRooms = 7

h.description

//Size of Hotel: 10 rooms capacity:3/10

h.bookNumberOfRooms(room: 2)

// returns true

h.description

//Size of Hotel: 10 rooms capacity:5/10

h.bookNumberOfRoom()

// returns true

h.description

//Size of Hotel: 10 rooms capacity:6/10

Initializers (البادئ)

تعد init البادئ الافتراضي للاصناف. في دالة init, نقوم بتعيين القيم الأولية للنموذج الذي تم إنشاؤه.

مثلا, اذا احتجنا الى صنف فرعي لـ Hotel مع  100غرفة, ثم احتجنا الى بادئ لتعيين خاصية الغرف لـ 100. تذكر انني قمت مسبقا بتغيير الغرف من كونها ثابت الى متغير في صنف Hotel. ذلك لانه لا يمكننا تغيير الثوابت الموروثة في الصنف الفرعي, يمكن تغيير المتغيرات الموروثة فقط.
      

class BigHotel: Hotel {

    init() {

        super.init()

        rooms = 100

    }

}



let bh = BigHotel()

println(bh.description);

//Size of Hotel: 100 rooms capacity:0/100

يمكن للبادئ ان يأخذ معاملات أيضا. يوضح لك المثال التالي كيفية عمل ذلك.

      
class CustomHotel: Hotel {

    init(size:Int) {

        super.init()

        rooms = size

    }

}



let c = CustomHotel(size:20)

c.description

//Size of Hotel: 20 rooms capacity:0/20

هيمنة الطرق و الخواص المحسوبة

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

class CustomHotel: Hotel {

    init(size:Int) {

        super.init()

        rooms = size

    }

    override var description:String {

        return super.description + " Howdy!"

    }

}



let c = CustomHotel(size:20)

c.description

// Size of Hotel: 20 rooms capacity:0/20 Howdy!

بالنتيجة يعود الوصف بنتيجة طريقة وصف الصنف العلوي مع نص "Howdy!" ملحق به.

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

لا اعلم كم عدد المرات التي جعلني فيها خطأ مطبعي في طريقة مهيمنة في Objective-C ان اشتم, ذلك لان الكود لم تكن تعمل. في swift, سيخبرك المجمع ما هو الخطأ بالضبط في هذه الحلات.

البنى

تعرف البنى بالكلمة الأساسية struct و تعد اقوى في swift من C و من Objective-C. في C ,تعرف structs القيم و المؤشرات فقط. تشبه  structs البنى في C, و لكنهم يدعمون أيضا الخواص المحسوبة و الطرق.

كل شيء تفعله بالصنف, يمكنك ان تفعله بالبنية, مع اختلافين بسطين:
  •      لا تدعم البنى الإرث كما هو الحال مع الأصناف
  •      يتم تمرير البنى من خلال قيمة بينما يتم تمرير الأصناف من خلال مرجع

ها هنا بعض الأمثلة عن البنى في swift:

      
struct Rect {

    var origin: Point

    var size: Size

    var area: Double {

        return size.width * size.height

    }

    func isBiggerThanRect(r:Rect) -> Bool {

        return (self.area > r.area)

    }

}



struct Point {

    var x = 0

    var y = 0

}

   

struct Size {

    var width = 0

    var height = 0

}

4. Optionals

الحل لمشكلة

يعد مفهوم الخيارات جديدا اذا كنت تتعامل مع Objective-C. يقومون بحل مشكلة نواجهها كمبرمجين. عندما نصل الى متغير لسنا واثقين من قيمته, نقوم عادة بارجاع مؤشر, يعرف بالحارس, ليدل ان القيمة المرجعة هي لا-قيمة. دعوني أوضح ذلك من خلال مثال من Objective-C:

      
NSString* someString = @"ABCDEF";

NSInteger pos = [someString rangeOfString:@"B"].location;



// pos = 1

في المثال السابق, نحاول إيجاد موقع @"B" في someString. اذا وجدت @"B", موقعها يخزن في pos. و لمن ما الذي يحصل اذا لم نجد @"B"في someString؟

ينص التصريح على ان rangeOfString: تعود بـ NSRange مع موقع يعين لثابت NSNotFound. في حالة rangeOfString:, يكون الحارس NSNotFound. يستخدم الحراس للإشارة على ان القيمة المرجعة غير صالحة.

في Cocoa, هنالك عدة استخدامات لهذا المفهوم, و لكن قيمة الحارس تختلف من مجال الى اخر, 0, -1, NULL, NSIntegerMax, INT_MAX, Nil,, الخ. مشكلة المبرمجة هي انها يجب ان تتذكر أي حارس استخدم في أي مجال. في لم تكن المبرمجة حذرة, يمكنها ان تخطئ فتعتقد ان القيمة الصالحة هي لحارس و بالعكس. يحل swift هذه المشكلة من خلال الاختيارات. لنقتبس كلام Brian Lanier "تعد الخيارات الحارس الوحيد لحكمهم جميعا".



لدى الخيارات حالتان, حالة الصفر, و التي تعني ان الخيار يحوي على لا قيمة, و حالة ثانية, تعني انه يحوي على قيمة صالحة. تخيل الخيارات كرزمة مع مؤشر يخبرك فيما اذا كانت محتويات الرزمة صالحة ام لا.

الاستخدام

يمكن لكل الأنواع في swift ان تصبح خيار. نقوم بتعريف الخيار من خلال إضافة ؟ بعد تصريح النوع مثل:
      
let someInt: Int?



// someInt == nil

نقوم بتعيين قيمة لرزمة الخيار تماما كما فعلنا مع ثوابت 1 و المتغيرات.
      

someInt = 10



// someInt! == 10

تذكر ان الخيارات هي فقط رزم. عندما تعلن عن let someInt: Int?, سنقوم بتعريف صندوق فارغ مع قيمة صفر. من خلال تعيين القيمة 10 للخيار, سيحتوي الصندوق على رقم مساو لـ 10 و يصبح مؤشره أو حالته ليست الصفر.

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

if ( someInt != nil) {

    println("someInt: \(someInt!)")

} else {

    println("someInt has no value")

}



// someInt: 10

يعد النمط السابق شائعا في swift الى درجة انه يمكننا تبسيط تكتل الكود من خلال استخدام ربط الخيارات مع الكلمات الأساسية if let. الق نظرة على الكود المحدث اسفلا.

      
if let value = someInt {

    println("someInt: \(value)")

} else {

    println("someInt has no value")

}

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

5. إدارة الذاكرة

اذا كنت تتذكر, عندما تم تقديم ARC كنا نستخدم الكلمات الأساسية الضعيفة و القوية لتعريف ملكية الكائنات. لدى swift أيضا نموذج ملكية ضعيف و قوي, و لكنه يقدم واحدا جديدا, غير مملوك. دعونا نلقي نظرة على كل نموذج ملكية كائن في swift.

القوي

تعد المراجع القوية افتراضية في swift. في معظم الوقت, نملك الكائن الذي نشير اليه و نحن المسؤولون عن المحافظة على حياة الكائن المرجع.

بما ان المراجع القوية تعد افتراضية, فليس هنالك داع لترك بشكل واضح مرجع قوي لكائن ما, كل مرجع هو مرجع قوي.

الضعيف

يدل المرجع الضعيف في swift على ان المرجع يشير الى كائن لسنا مسؤولين عن حياته. يستخدم بشكل أساسي بين كائنين لا يحتاجان احدهما ليكون حول الاخر من اجل اكمال دورة حياته.

و لكن هنالك لكن واحدة. في swift, يجب على المراجع الضعيفة ان تكون متغيرات مع نوع خيار, لأننا نعينهم لصفر عندما يتم فصل الكائن المرجع. يستخدم الكلمة الأساسية weak للإعلان عن المتغير كضعيف:    
weak var view: UIView?

غير المملوكة

تعد المراجع غير المملوكة جديدة مبرمجي على Objective-C. المرجع غير المملوك يعني اننا غير مسؤولين عن المحافظة على حياة الكائن المرجع, كما هي الحال مع المراجع الضعيفة.


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

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

      
unowned var view: UIView

الخاتمة

تعد  swiftلغة رائعة لديها الكثير من العميق و الإمكانيات. من الممتع كتابة برمج باستخدامها و تزيل الكثير من boilerplate الكود التي نكتبها في Objective-C لنحرص على ان الكود امنة.

انصحكم بشدة لاستخدام لغة البرمجة swift, التي تتواجد مجانا في مخزن Apple's iBooks.

الكــاتــب

    • مشاركة

ليست هناك تعليقات:

جميع الحقوق محفوظة لــ الشبح للمعلوميات 2019 ©