Xcode เปลี่ยนสตอรี่บอร์ดและไฟล์ XIB ที่ไม่ได้แก้ไข


132

สตอรีบอร์ดเป็นความเจ็บปวดจากมุมมองของกระบวนการทำงานแบบคอมไพล์เมื่อมีคนหลายคนทำงานร่วมกัน ตัวอย่างเช่น XML ในไฟล์. สตอรี่บอร์ดมี<document>แท็กเริ่มต้นtoolsVersionและsystemVersionแอตทริบิวต์ที่เปลี่ยนแปลงโดยการกำหนดค่าใด ๆ ก็ตามที่เครื่องมือจัดการไฟล์ล่าสุดกำลังทำงานอยู่ การซิงโครไนซ์เวอร์ชัน Xcode ของทุกคนดูเหมือนจะช่วยได้อย่างแม่นยำtoolsVersionแต่systemVersionจะมีการเปลี่ยนแปลงไม่ว่าจะเป็นอย่างไรทั้งนี้ขึ้นอยู่กับเวอร์ชัน Mac และ / หรือ OS X ที่นักพัฒนาใช้งานอยู่

นี่เป็นเรื่องงี่เง่า แต่ส่วนใหญ่ไม่เป็นอันตราย สิ่งที่ทำให้เรากังวลคือในบางครั้งการเปลี่ยนแปลงอื่น ๆ จะเกิดขึ้นโดยอัตโนมัติกับสตอรีบอร์ดเพียงแค่เปิดหลังจากไฟล์git pull. กล่าวคืออลิซทำการเปลี่ยนแปลงกับสตอรีบอร์ดยอมรับและผลักดันไปยังที่เก็บ จากนั้นบ็อบดึงการเปลี่ยนแปลงของอลิซและเปิดกระดานเรื่องราวเพื่อทำการเปลี่ยนแปลงเพิ่มเติม ทันทีที่เขาเปิดกระดานเรื่องราวไอคอนไฟล์จะเปลี่ยนเป็นสถานะที่แก้ไข แต่ไม่ได้บันทึกทันทีและgit statusแสดงให้เห็นว่ามีการเปลี่ยนแปลงแปลก ๆ เกิดขึ้นจำนวนมาก ทั้งหมดนี้โดยที่ Bob ไม่ได้เปลี่ยนแปลงอะไรหรือบันทึกไฟล์ด้วยตัวเอง

การเปลี่ยนแปลงอัตโนมัติที่พบบ่อยที่สุดที่เราเห็นคือการหายไปหรือการปรากฏขึ้นอีกครั้งของ<classes>แท็กทั้งหมดที่อยู่ใกล้กับส่วนท้ายของไฟล์สตอรีบอร์ด เรายังไม่ทราบว่าอะไรเป็นสาเหตุของสิ่งนี้ เราอาจมีสตอรี่บอร์ดเวอร์ชันแปลหลายเวอร์ชันในไดเร็กทอรี. lproj ต่างๆและเมื่อเปิดภายในอินเทอร์เฟซ Builder ลำดับชั้นของคลาสอาจถูกลบออกจากบางเวอร์ชันและเพิ่มลงในเวอร์ชันอื่น ๆ หรือปล่อยให้อยู่คนเดียวในบางไดเร็กทอรี สิ่งนี้ทำให้เกิดเสียงดังgit diffมาก แต่ก็ไม่ได้ทำลายฟังก์ชันการทำงานใด ๆ เรามักจะเลือกเพิ่มการเปลี่ยนแปลงจริงที่เราทำลงในดัชนีของ git กระทำสิ่งเหล่านั้นจากนั้นก็ทิ้งสิ่งที่เกิดขึ้นเองและไร้สาระ<classes>ซ้ำของการเปลี่ยนแปลงนี่คือการกระทำเล็ก ๆ น้อย ๆ และดีอย่างที่ควรจะเป็น ในที่สุดแม้ว่าจะกลายเป็นเรื่องที่น่ารำคาญมากเกินไปเนื่องจาก Xcode ยังคงทำการเปลี่ยนแปลงซ้ำและมีคนเพียงแค่สั่งให้พวกเขาร่วมกับสิ่งอื่น ๆ ... ซึ่งก็ใช้ได้จนกว่า Xcode ของคนอื่นจะตัดสินใจว่าต้องการเปลี่ยนกลับโดยไม่ เหตุผลที่ชัดเจน (ประวัติการกระทำของเรามีคำสบถมากมายเกี่ยวกับเรื่องนี้)

มีใครอีกบ้างที่เห็นพฤติกรรมนี้ นี่เป็นข้อบกพร่องของ Xcode หรือปัญหาการกำหนดค่าใน Mac ของนักพัฒนาซอฟต์แวร์ของเราอย่างน้อยหนึ่งเครื่อง? เราเคยเห็นพฤติกรรมบางอย่างที่คล้ายกันเมื่อทำงานร่วมกับไฟล์ XIB แต่สตอรีบอร์ดดูเหมือนจะอ่อนไหวต่อสิ่งนี้มากกว่า


อันที่จริงโครงการ Xcode และ Git ทำงานร่วมกันได้ไม่ดีนัก ฉันไม่คิดว่าคุณจะหลีกเลี่ยงความยุ่งเหยิงนี้ได้ด้วยวิธีอื่นนอกจากการทิ้งการเปลี่ยนแปลงที่ไม่จำเป็นนั่นคือไฟล์โปรเจ็กต์มักจะเปลี่ยนแปลงสำหรับฉันและไฟล์ xml อื่น ๆ ฉันแน่ใจว่าฉันไม่ได้เปลี่ยนแปลง จะดีใจถ้ามี 'วิธีแก้ปัญหา' ประเภทใด ๆ ฉันชอบ Perforce สำหรับฟังก์ชั่นล็อคที่สะดวกไม่อนุญาตให้ Xcode เปลี่ยนแปลงมากเกินไปซึ่งอาจทำได้ด้วยตนเองสำหรับไฟล์ที่คุณจะไม่เปลี่ยนแปลง แต่เพื่อตรวจสอบเท่านั้น
A-Live

3
ไม่คุ้มที่จะใช้สตอรี่บอร์ดกับคอมไพล์หรืออย่างอื่น ไม่ได้ออกแบบมาให้ผูกมิตร เรายอมแพ้และไปกับ. xib ซึ่งไม่ใช่ทั้งหมดที่ยอดเยี่ยมเช่นกัน แต่อย่างน้อยมันก็ละเอียด
ahwulf

เราพบว่าสตอรี่บอร์ดค่อนข้างเรียบร้อยสำหรับหลาย ๆ อย่างจริง ๆ แล้วแม้ว่าจะต้องผสมกับ XIB ก็ตาม หากข้อบกพร่องนี้ได้รับการแก้ไขแล้วเรายินดีที่จะทำงานร่วมกับพวกเขาเป็นส่วนใหญ่
JK Laiho

ฉันแค่ต้องแสดงความคิดเห็นเกี่ยวกับความคิดเห็นของ ahwulf: คุณหมายความว่าอย่างไรในโลกนี้ที่พวกเขาไม่เป็นมิตร? เป็นไฟล์ XML / ข้อความซึ่งเกี่ยวกับการกระทำที่เป็นมิตรเท่าที่คุณจะทำได้ และฉันมีปัญหา 'ไม่' กับกระดานเรื่องราวและระบบการกำหนดเวอร์ชันปัญหาเดียวคือแน่นอนว่า xcode บางครั้งลบแท็ก <classes> แล้วอ่านในภายหลัง แต่คุณสามารถดูสิ่งนี้ได้อย่างง่ายดายหากคุณดูการเปลี่ยนแปลงด้วย git GUI หรือ git -p หรือเทียบเท่าสำหรับ dvcs ใด ๆ ฉันไม่เคยมีสิ่งนี้เกิดขึ้นกับไฟล์. pbxproj เป็น fyi
mgrandi

ฉันไม่เข้าใจว่าทำไม xcode จึงวางบล็อกชั้นเรียนไว้ในสตอรี่บอร์ดถ้าเขาสามารถสร้างบล็อกเหล่านั้นได้โดยการอ่านไฟล์คลาส? มันคือ "แคช" หรือเปล่า ถ้าเป็นเช่นนั้นควรใส่ไว้ในไฟล์ class.cache เพื่อที่เราจะได้แยกมันออกจากการกำหนดเวอร์ชัน ...
hariseldon78

คำตอบ:


78

นี่ไม่ใช่ข้อผิดพลาดนี่เป็นผลมาจากการที่ Xcode ประมวลผลไฟล์สตอรี่บอร์ด ฉันกำลังเขียนโปรแกรมที่แตกต่างและผสานสำหรับไฟล์สตอรีบอร์ด(ลิงก์ GitHub)และฉันใช้เวลาหลายชั่วโมงในการวิเคราะห์ตรรกะของไฟล์สตอรีบอร์ดและวิธีการประมวลผล Xcode นี่คือสิ่งที่ฉันค้นพบ:

  • เหตุใดจึงมีการเปลี่ยนแปลงแปลก ๆ เกิดขึ้นในไฟล์สตอรีบอร์ด Xcode ใช้ NSXML API เพื่อแยกวิเคราะห์ไฟล์สตอรีบอร์ดเป็นNSSetโครงสร้างแบบลอจิคัลทรี เมื่อ Xcode จำเป็นต้องเขียนการเปลี่ยนแปลงมันจะสร้างโครงสร้างNSXMLDocumentตามตรรกะของต้นไม้ให้ล้างไฟล์สตอรี่บอร์ดและเรียกXMLDataWithOptions:เติมไฟล์อีกครั้ง เนื่องจากชุดไม่รักษาลำดับขององค์ประกอบแม้การแก้ไขเพียงเล็กน้อยก็สามารถเปลี่ยนไฟล์ XML ของกระดานเรื่องราวทั้งหมดได้

  • เหตุใดแท็กชั้นเรียนจึงหายไปหรือปรากฏขึ้นใหม่แบบสุ่ม <class>ส่วนคืออะไรมากกว่าแคช Xcode ภายใน Xcode ใช้เพื่อแคชข้อมูลเกี่ยวกับคลาส แคชเปลี่ยนแปลงบ่อย องค์ประกอบจะถูกเพิ่มเมื่อ.h/.mเปิดและลบไฟล์คลาสเมื่อ Xcode สงสัยว่าล้าสมัย (อย่างน้อย Xcodes ที่เก่ากว่าจะทำงานเช่นนี้) เมื่อคุณบันทึกสตอรีบอร์ดแคชเวอร์ชันปัจจุบันจะถูกทิ้งซึ่งเป็นสาเหตุที่<class>ส่วนนี้มักจะเปลี่ยนไปหรือหายไป

ฉันไม่มี Xcode ที่ทำวิศวกรรมย้อนกลับ ฉันตั้งข้อสังเกตเหล่านี้โดยการทดลองกับ Xcode และไฟล์สตอรี่บอร์ด อย่างไรก็ตามฉันมั่นใจเกือบ 100% ว่ามันทำงานในลักษณะนี้

สรุป :

  • ส่วนแคชไม่สำคัญ คุณสามารถเพิกเฉยต่อการเปลี่ยนแปลงใด ๆ ได้อย่างปลอดภัย
  • ตรงกันข้ามกับสิ่งที่คุณสามารถพบได้ในทุกฟอรัมการรวมไฟล์สตอรี่บอร์ดไม่ใช่งานที่ซับซ้อน ตัวอย่างเช่นสมมติว่าคุณเปลี่ยนตัวMyController1ควบคุมมุมมองในเอกสารสตอรี่บอร์ด <viewController id=”ory-XY-OBM” sceneMemberID=”MyController1”>เปิดแฟ้มสตอรี่บอร์ดและหาบางสิ่งบางอย่างเช่นนี้ คุณสามารถยอมรับเฉพาะการเปลี่ยนแปลงในส่วนนี้ได้อย่างปลอดภัยและไม่ต้องสนใจสิ่งอื่นใด หากคุณเปลี่ยน segues หรือข้อ จำกัด ให้ยอมรับสิ่งที่มี“ory-XY-OBM”อยู่ภายในด้วย ! ง่าย

9
มีการอัปเดตบนเครื่องมือ xcode diff / merge หรือไม่ ดูเหมือนจะมีประโยชน์อย่างยิ่งสำหรับชุมชนนี้
Tony

1
คุณสามารถรับแอปได้จากหน้าเว็บของฉัน (ดูโปรไฟล์) แอปฟรี 100%
Marcin Olawski

1
สำหรับฉันแบ่งสตอรี่บอร์ดให้มากที่สุด == โดยใช้ XIB หากคุณต้องการหั่นทุกอย่างให้ใช้
XIB

7
"ฉันไม่ได้ออกแบบ Xcode แบบย้อนกลับฉันทำการสังเกตเหล่านี้โดยการทดลองกับ Xcode และไฟล์สตอรี่บอร์ด" นั่นคือวิศวกรรมย้อนกลับ (ตื้น ๆ ) และมันเจ๋งมาก :-)
Constantino Tsarouhas

13
"นี่ไม่ใช่ข้อบกพร่องนี่เป็นผลมาจากวิธีที่ Xcode ประมวลผลไฟล์สตอรีบอร์ด" ด้วยความเคารพครึ่งหลังของประโยคนี้ไม่ได้อธิบายหรือหาเหตุผลให้กับประโยคแรก ฉันจะแก้ไขเป็น: "นี่เป็นข้อบกพร่องมันเป็น [n ที่ยังไม่ได้รับการแก้ไขและน่ารำคาญอย่างมาก] ผลที่ตามมาของวิธีการที่ XCode ประมวลผลไฟล์. xib" จาก XCode 5.x ถึง 6.2 (วันนี้ 150311) ไฟล์. xib ไม่ได้แก้ไขโดยนักพัฒนาเพียงแค่ดูใน IB ได้รับการเปลี่ยนแปลง xml โดยไม่จำเป็น นี่คือข้อบกพร่องขั้นต้นที่ส่งผลกระทบต่อผลผลิต คำตอบเช่น "NBD เพียงแค่จัดการกับชิ้นส่วนในคอมไพล์" ทำให้ฉันพูดไม่ออก
cweekly

18

นี่เป็นข้อบกพร่องใน XCode 4.5+ ฉันหวังว่ามันจะได้รับการแก้ไขและใช่มันเป็น PITA

นี่คือข้อบกพร่องทั้งหมดของ Apple

จะหลีกเลี่ยงการแก้ไข Xcode ไปยังไฟล์สตอรี่บอร์ดโดยไม่จำเป็นได้อย่างไร


1
สิ่งเดียวกันใน 4.6 อาจจะไม่ใช่บั๊ก
Thromordyn

4.6.3 ยังมีอยู่ ไม่สามารถพูดได้ว่าสตอรี่บอร์ด / xibs ทำงานได้ดี
houbysoft

1
"ไม่ใช่บั๊ก แต่เป็นฟีเจอร์": -S
MrTJ

ไม่มีหลักฐานว่านี่เป็นข้อผิดพลาด - น่ารำคาญใช่ แต่อาจเป็นเพียงวิธีที่ Xcode ทำสิ่งต่างๆ
Thomas Watson

1
7.0.1 ไม่ได้ทำการเปลี่ยนแปลงใด ๆ กับสิ่งนี้
Andris Zalitis

11

ปัญหานี้สามารถบรรเทาลงได้บ้างโดยการใช้git add -pไฟล์ที่สร้างขึ้นของ Xcode อย่างรอบคอบรวมถึงสตอรี่บอร์ด XIB โมเดลข้อมูลหลักและไฟล์โครงการซึ่งทั้งหมดนี้ได้รับผลกระทบจากการแก้ไขชั่วคราวที่คล้ายกันซึ่งไม่มีผลกระทบต่ออินเทอร์เฟซ / โมเดลจริง / โครงการ.

การเปลี่ยนแปลงขยะที่พบบ่อยที่สุดที่ฉันเคยเห็นบนสตอรีบอร์ดคือหมายเลขเวอร์ชันของระบบ (ตามที่คุณกล่าวถึง) และการเพิ่มและลบ<classes>ส่วนอย่างต่อเนื่องซึ่งการละเว้นซึ่งฉันไม่เคยเห็นทำให้เกิดปัญหา สำหรับ XIB เป็นการเพิ่มและลบ<reference key="NSWindow"/>ซึ่งไม่ใช่คลาสใน Cocoa Touch ว้าว

คิดว่าเหมือนทะเลมีทั้งน้ำขึ้นและน้ำลง ปล่อยให้มันล้างคุณ

อ่า แค่นั้นแหละ.

คุณสามารถเพิกเฉยต่อการแก้ไขเหล่านี้เมื่อจัดเตรียมการเปลี่ยนแปลงรีเซ็ตการเปลี่ยนแปลงขยะและทำการคอมมิตใหม่ทั้งหมด

ข้อได้เปรียบเดียวที่ฉันเคยเห็นกับสตอรี่บอร์ดผ่าน XIB จากมุมมองทางเทคนิคคือ Apple ยังไม่ได้สร้าง FileMerge เพื่อปฏิเสธที่จะรวมสตอรีบอร์ดที่ขัดแย้งกัน (FileMerge เคยสามารถผสาน XIB ได้ แต่เวอร์ชันที่ใหม่กว่านั้นทำไม่ได้พวก Thxxxx 💜 !!!)

โปรดแจ้งข้อบกพร่องมากมายเกี่ยวกับปัญหาเหล่านี้ที่http://bugreporter.apple.com/ ! และไม่ลืมที่จะสร้างรายการในOpenRadar


6

โยนคำตอบอื่นที่นี่เพราะสถานการณ์นี้ดีขึ้นมาก XML สำหรับไฟล์ XIB ที่แสดงถึง StoryBoard นั้นง่ายขึ้นมาก

ฉันเพิ่งกัดกระสุนและเริ่มใช้อินเทอร์เฟซใน Xcode กับ Source Control ฉันอยู่ในบรรทัดคำสั่งมาหลายปีแล้วและมีความสุขที่นั่น แต่อินเทอร์เฟซนั้นดีและช่วยให้คุณแยกคอมมิตได้ซึ่งสำคัญมากหากคุณใช้ระบบการออกตั๋วที่เชื่อมโยงไปยังคอมมิต

อย่างไรก็ตามวันนี้ฉันสังเกตเห็นว่ามีการเปลี่ยนแปลงบนกระดานเรื่องราวและ built in diff แสดงให้ฉันเห็นว่ามันเป็นแอตทริบิวต์เดียวในแท็กเอกสาร (systemVersion) ดังนั้นไม่ใช่เรื่องใหญ่

ฉันได้อ่านบทความที่มีคนบอกว่า SB ถูกผิดกฎหมายในทีมของพวกเขาเนื่องจากปัญหาการรวมกัน ความบ้าคลั่งทั้งหมด พวกเขาน่าทึ่งมากโดยเฉพาะอย่างยิ่งตอนนี้พวกเขามีระบบอัตโนมัติอัจฉริยะในตัวคุณจะพลาดถ้าคุณไม่ได้ใช้มัน


3

เป็นประโยชน์ที่จะทราบว่าเหตุใดจึงเกิดความวิกลจริตนี้ขึ้น แต่สำหรับผู้ที่เชื่อมั่นในการรักษาโครงการของตนให้ปราศจากคำเตือนและผู้ที่ต้องการความรวดเร็วและสกปรกเพื่อให้โครงการของพวกเขากลับสู่สภาพที่สมบูรณ์:

  1. อย่าทำอะไรจนกว่าจะได้รับคำสั่งอย่างชัดเจน

  2. เปิด Xcode และสร้างสตอรี่บอร์ดใหม่ (Command + N> iOS> User Interface> Storyboard) ฉันจะถือว่าคุณเรียกมันว่าชื่อเริ่มต้นของStoryboard.storyboard.

  3. เปิดกระดานเรื่องราวที่ Xcode ละเมิด Base.lproj/Main.storyboardฉันจะถือว่านี้คือ

  4. เลือกและคัดลอกทุกอย่างบนกระดานเรื่องราว (Command + A แล้ว Command + C)

  5. Storyboard.storyboardเปิด

  6. Storyboard.storyboardคัดลอกและวางทุกอย่างลง

  7. ปิด Xcode

  8. เปิดเทอร์มินัลและเปลี่ยนไดเร็กทอรีเป็นที่เก็บของคุณ

  9. แทนที่Main.storyboardด้วยStoryboard.storyboard( mv Storyboard.storyboard Base.lproj/Main.storyboard)

  10. git add Base.lproj/Main.storyboard; git commit -m "Fix Xcode's insanity."

  11. ไม่สนใจการเปลี่ยนแปลงproject.pbxprojผ่านgit checkout -- project.pbxproj. หากคุณgit diffเป็นไฟล์คุณจะเห็นว่าเพิ่งเพิ่มข้อมูลเกี่ยวกับสตอรีบอร์ดชั่วคราวของเรา (ซึ่งไม่มีอยู่แล้ว)

  12. เปิด Xcode สำรองและดูว่าคำเตือนหายไป

  13. หายใจ.


0

การทำงานบนสตอรีบอร์ดเดียวกันไม่ใช่ปัญหา แต่การทำงานกับตัวควบคุมมุมมองเดียวกันซึ่งสร้างความขัดแย้งในการดึง / ผสานนั้นน่ากลัว เราไม่สามารถหลีกเลี่ยงการทำงานในตัวควบคุมมุมมองเดียวกันสำหรับทีมขนาดใหญ่ได้

สิ่งที่ดีคือโดยส่วนใหญ่เราสามารถแก้ไขความขัดแย้งของ viewcontroller เดียวกันได้หากเราเข้าใจโครงสร้าง xml ฉันไม่เคยล้มเหลวในการผสานสิ่งเหล่านี้ขณะทำงานเป็นทีม สมมติว่าคุณกำลังทำงานกับ viewcontroller ขณะนี้มุมมองของคุณว่างเปล่า โปรดดูโครงสร้าง xml ของ viewcontroller จากตัวเลือกซอร์สโค้ด

ป้อนคำอธิบายภาพที่นี่

สตอรี่บอร์ดเป็น xml ล้อมรอบด้วยแท็กประเภทเอกสาร ทุกอย่างในสตอรี่บอร์ดมีในแท็ก scene sceneID = แท็กฉากมีตัวควบคุมมุมมองทุกตัว นั่นคือพื้นฐาน

ตอนนี้เราได้เพิ่ม UILabel และ UIButton ในมุมมอง ตั้งค่าการจัดวางองค์ประกอบอัตโนมัติด้วย ตอนนี้ดูเหมือนว่า:

ป้อนคำอธิบายภาพที่นี่

การเพิ่มระดับ / ปุ่มใน viewcontroller ได้เพิ่มโค้ดใหม่บางส่วนภายในแท็ก subview ของมุมมอง สิ่งเดียวกันจะไปสำหรับการเพิ่มองค์ประกอบเพิ่มเติมหรือการเปลี่ยนแปลง UI ใด ๆ ตรวจสอบโครงสร้างแท็กอย่างละเอียดซึ่งสำคัญมากในการแก้ไขข้อขัดแย้ง

ตอนนี้เราเพิ่ม viewcontroller อีกตัวในชื่อสตอรี่บอร์ด Homeviewcontroller การเพิ่มวิวคอนโทรลเลอร์ใหม่หมายความว่าจะเพิ่มฉากใหม่ภายใต้แท็กฉาก ดูนี่สิ:

ป้อนคำอธิบายภาพที่นี่

ณ จุดนี้เราจะเปลี่ยนโครงสร้างแบบสุ่มและสังเกตประเด็น / คำเตือน เราเปลี่ยนแท็กปิดท้ายฉลากของวิวคอนโทรลเลอร์แรกและบันทึกไฟล์ ตอนนี้เรียกใช้และดูคำเตือน ข้อผิดพลาดแจ้งว่าแท็กปิดท้ายไม่ถูกต้องซึ่งสร้างจากบรรทัด 23 ในบรรทัดที่ 23 เราเห็นข้อ จำกัด ของป้ายกำกับถูกตั้งค่าโดยไม่มีแท็กปิดท้าย นั่นคือปัญหา. ตอนนี้เราใส่แท็กปิดท้ายและสร้างโครงการ หลังจากตั้งค่าแท็กปิดท้ายเราสามารถดูสตอรี่บอร์ดได้สำเร็จ

ป้อนคำอธิบายภาพที่นี่

เมื่อเผชิญกับคำเตือนเกี่ยวกับความขัดแย้งโปรดเปรียบเทียบกับแหล่งที่มาก่อนหน้าของคุณและแหล่งที่มาของการเปลี่ยนแปลง เราลบรหัสเก่า / ซ้ำซ้อนเก็บรหัสใหม่ด้วยการเริ่มต้นแท็กที่เหมาะสมและแก้ไขสิ่งต่างๆ

[หมายเหตุฉันจะอัปเดตคำตอบพร้อมกรณีทดสอบเพิ่มเติมเมื่อได้รับ]

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.