مؤشرات المخازن المؤقتة غير الآمنة
عالج الذاكرة المتجاورة بكفاءة.
مؤشرات المخازن المؤقتة غير الآمنة درس مجاني في Swift Academy على CoddyKit. هذا هو الدرس 3 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في Swift Academy، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة Swift Academy 4 دروس في المجموع.
ما هو مؤشر المخزن المؤقت
يشير المؤشر ذو النوع المحدد إلى عنصر واحد في كل مرة. يغلّف UnsafeBufferPointer<T> مؤشر بداية بالإضافة إلى عدد، ويوفر عرضًا محدود النطاق لكتلة متجاورة من الذاكرة تطبّق Collection.
وهذا يعني أنه يمكنكم التكرار، واستخدام subscript وmap وreduce — أي استخدام واجهات برمجة المجموعات المألوفة على الذاكرة الخام.
// A buffer pointer = base address + element count
// UnsafeBufferPointer<Int>(start: ptr, count: 5)المخازن المؤقتة للقراءة فقط مقابل القابلة للتعديل
مثل المؤشرات المفردة، تأتي المخازن المؤقتة بنوعين: UnsafeBufferPointer<T> للتكرار للقراءة فقط، وUnsafeMutableBufferPointer<T> عندما تحتاجون أيضًا إلى إسناد قيم إلى العناصر.
let p = UnsafeMutablePointer<Int>.allocate(capacity: 4)
p.initialize(repeating: 0, count: 4)
let buf = UnsafeMutableBufferPointer(start: p, count: 4)
buf[0] = 11
print(buf[0]) // 11التكرار مثل المجموعات
بما أن مؤشر المخزن المؤقت هو Collection، فإن حلقة for تمرّ على كل عنصر بالترتيب. لا حاجة إلى حساب فهارس يدويًا، ولا خطر تجاوز الحد في الحلقة نفسها — مع أن الحدود التي حددتموها تظل مسؤوليتكم.
let buf = UnsafeMutableBufferPointer<Int>.allocate(capacity: 3)
_ = buf.initialize(from: [10, 20, 30])
for value in buf { print(value) } // 10, 20, 30خوارزميات المجموعات بلا تكلفة إضافية
تعمل كل من map وfilter وreduce وenumerated وindices على مؤشرات المخازن المؤقتة. يتيح لكم ذلك معالجة الذاكرة الخام باستخدام تعليمات برمجية عالية المستوى مع الاستغناء عن التخصيصات.
let buf = UnsafeMutableBufferPointer<Int>.allocate(capacity: 4)
_ = buf.initialize(from: [1, 2, 3, 4])
let total = buf.reduce(0, +) // 10
let evens = buf.filter { $0 % 2 == 0 } // [2, 4]
print(total, evens)تخصيص مخزن مؤقت قابل للتعديل
تحجز UnsafeMutableBufferPointer<T>.allocate(capacity:) الكتلة وتعيد مخزنًا مؤقتًا في خطوة واحدة. ومع ذلك، يجب عليكم تنفيذ initialize قبل القراءة وdeallocate عند الانتهاء.
let buf = UnsafeMutableBufferPointer<Int>.allocate(capacity: 5)
buf.initialize(repeating: 0)
defer {
buf.deinitialize()
buf.deallocate()
}لا يُتحقق من الحدود عند الحافة
يُعد استخدام subscript داخل 0..<count آمنًا. لكن المخزن المؤقت لا يستطيع معرفة ما إذا كان العدد الذي زودتموه صحيحًا. إذا أنشأتم مخزنًا مؤقتًا بعدد أكبر من حجم التخصيص الفعلي، فستتجاوز القراءات النهاية إلى ذاكرة غير معرّفة.
استمدوا العدد دائمًا من التخصيص نفسه الذي أنشأتموه.
let p = UnsafeMutablePointer<Int>.allocate(capacity: 3)
p.initialize(repeating: 0, count: 3)
// CORRECT: count matches capacity
let good = UnsafeBufferPointer(start: p, count: 3)
// WRONG: count: 10 would read past the block
print(good.count)المخازن المؤقتة الفارغة
المخزن المؤقت الذي تكون قيمة count: 0 فيه صالحًا، وقد يكون عنوانه الأساسي nil. تحققوا دائمًا من isEmpty أو اتركوا الحلقة لا تُنفذ ببساطة، بدلًا من فرض فك تغليف baseAddress.
let empty = UnsafeBufferPointer<Int>(start: nil, count: 0)
print(empty.isEmpty) // true
print(empty.count) // 0
for _ in empty { print("never runs") }استخدام withUnsafeBufferPointer مع المصفوفات
الطريقة الأكثر أمانًا للحصول على مخزن مؤقت هي استخدام Array موجودة عبر withUnsafeBufferPointer. تضمن Swift أن مساحة التخزين متجاورة وصالحة طوال مدة closure، وبذلك تتجنبون التخصيص اليدوي بالكامل.
let numbers = [4, 8, 15, 16, 23]
let maxValue = numbers.withUnsafeBufferPointer { buf -> Int in
var m = buf[0]
for v in buf where v > m { m = v }
return m
}
print(maxValue) // 23تعديل مساحة تخزين المصفوفة
يتيح لكم withUnsafeMutableBufferPointer الكتابة مباشرةً في مساحة تخزين المصفوفة. ويُستخدم هذا أحيانًا لتحويلات داخلية مهمة للأداء، حيث قد تضيف ARC وفحوصات الحدود تكلفة إضافية.
var data = [1, 2, 3, 4]
data.withUnsafeMutableBufferPointer { buf in
for i in buf.indices { buf[i] *= 10 }
}
print(data) // [10, 20, 30, 40]استخدام baseAddress مع واجهات C
عند استدعاء دالة C تتوقع مؤشرًا وطولًا، مرروا buffer.baseAddress وbuffer.count. يكون العنوان الأساسي nil فقط مع المخازن المؤقتة الفارغة، لذا تعاملوا مع هذه الحالة.
let bytes: [UInt8] = [0xDE, 0xAD, 0xBE, 0xEF]
bytes.withUnsafeBufferPointer { buf in
if let base = buf.baseAddress {
// c_function(base, buf.count)
print("start:", base, "len:", buf.count)
}
}متى تستخدمون مؤشرات المخزن المؤقت
استخدموا مؤشرات المخزن المؤقت عندما تحتاجون إلى وصول متجاور وآمن من ناحية النوع وبأسلوب المجموعات إلى منطقة من الذاكرة، مثل ربط مصفوفات C، أو تحليل التنسيقات الثنائية، أو تقليل التكلفة في الحلقات الساخنة. فضّلوا صيغ closure التي تبدأ بـ with... على التخصيص اليدوي كلما أمكن.
// Counting set bits across a byte buffer
let data: [UInt8] = [0b1011, 0b0110, 0b1111]
let bits = data.withUnsafeBufferPointer { buf in
buf.reduce(0) { $0 + $1.nonzeroBitCount }
}
print(bits) // 3 + 2 + 4 = 9اختبار سريع
تذكروا ما الذي يضيفه مؤشر المخزن المؤقت مقارنةً بالمؤشر المفرد.
مراجعة
تغلّف مؤشرات المخازن المؤقتة منطقة متجاورة في صورة مجموعة محدودة النطاق:
UnsafeBufferPointer/UnsafeMutableBufferPointer= عنوان أساسي + عدد.- تحصلون على
mapوfilterوreduceوالتكرار باستخدامforفوق الذاكرة الخام. - فضّلوا استخدام
withUnsafeBufferPointerمع المصفوفات لكي تدير Swift الصلاحية ومدة البقاء. - يُوثق بالعدد المقدم — لذا استمدوه من التخصيص الفعلي.
الأسئلة الشائعة
هل درس «مؤشرات المخازن المؤقتة غير الآمنة» مجاني؟
نعم — نص درس «مؤشرات المخازن المؤقتة غير الآمنة» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة Swift Academy، انتقل إلى CoddyKit PRO. تتضمن دورة Swift Academy 4 دروس في المجموع.
ماذا ستتعلم في «مؤشرات المخازن المؤقتة غير الآمنة»؟
عالج الذاكرة المتجاورة بكفاءة. تتمرن على Swift Academy مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.
هل أحتاج إلى خبرة سابقة لأبدأ Swift Academy؟
لا تُشترط خبرة سابقة. Swift Academy على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 3 من أصل 4.
كم من الوقت يستغرق درس «مؤشرات المخازن المؤقتة غير الآمنة»؟
معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.
هل يمكنني كتابة وتشغيل أكواد في درس Swift Academy هذا؟
نعم. كل درس في Swift Academy يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.
جميع الدروس في هذه الدورة
- MemoryLayout والمحاذاة
- UnsafePointer و UnsafeMutablePointer
- مؤشرات المخازن المؤقتة غير الآمنة
- withUnsafeBytes والتكامل مع C