อัปเดต: ปลั๊กอิน Xcode เดิมนี้ได้รับการจัดระเบียบใหม่เป็นแพ็คเกจ Swift เพื่อใช้ในแอปอื่น ใช้ผลิตภัณฑ์ Xprobe
ในแอปพลิเคชันไคลเอนต์และผลิตภัณฑ์ XprobeUI
ที่ฝั่งเซิร์ฟเวอร์
XprobePlugin ช่วยให้คุณมองเห็นออบเจ็กต์ภายในแอปพลิเคชันของคุณโดยละเอียดจนถึงระดับของ ivar หรือโดยรวมเป็นกราฟของออบเจ็กต์หลักและวิธีการเชื่อมต่อของออบเจ็กต์เหล่านั้น จอแสดงผลนี้สามารถเคลื่อนไหวได้แบบเรียลไทม์ โดยเน้นด้วยวัตถุสีแดงขณะที่ได้รับข้อความและเส้นทางที่ข้อความกำลังไหลลงมา สิ่งนี้ทำได้โดยอัตโนมัติโดยการ "กวาด" เพื่อค้นหาวัตถุทั้งหมดที่อ้างถึงโดยชุดของเมล็ด วัตถุที่พวกมันอ้างถึง วัตถุที่อ้างถึงและอื่น ๆ เพื่อสร้างรายการของวัตถุสดที่สามารถแสดงใน Xcode : :
ในเครื่องจำลอง ตัวกวาดหน่วยความจำจะถูกโหลดจากบันเดิลภายในปลั๊กอินโดยใช้ lldb โดยไม่จำเป็นต้องเปลี่ยนแปลงแหล่งที่มาของโปรเจ็กต์ของแอป หากต้องการใช้ปลั๊กอิน ให้สร้างโปรเจ็กต์นี้แล้วรีสตาร์ท Xcode เมื่อแอปพลิเคชันของคุณทำงาน ให้ใช้รายการเมนู "ผลิตภัณฑ์/Xprobe/โหลด" เพื่อโหลดมุมมองเริ่มต้นของการกวาดล้างหน่วยความจำของแอปของคุณ หากคุณเป็นนักพัฒนาปลั๊กอิน คุณจะใช้ "Product/Xprobe/Xcode" เพื่อตรวจสอบออบเจ็กต์ของแอปพลิเคชัน Xcode
จากนั้นคุณสามารถกรองออบเจ็กต์ที่แสดงอยู่ในแอพหรือวิธีการโดยใช้รูปแบบได้ หากไม่มีวัตถุที่ตรงกับรูปแบบและเป็นชื่อคลาสก็จะปรากฏขึ้น รูปแบบที่ขึ้นต้นด้วย '+' หรือ '-' จะค้นหาคลาสทั้งหมดที่เชื่อมโยงกับแอปพลิเคชันเพื่อหาวิธีการที่ตรงกับรูปแบบ คุณสามารถป้อนตัวชี้ดิบที่นำหน้าด้วย "0x" เพื่อตรวจสอบวัตถุที่ส่งผ่านเป็นอาร์กิวเมนต์ไปยังการติดตาม คุณยังสามารถป้อนวัตถุ "เส้นทาง" โดยเริ่มต้นจาก "seed" จากเส้นทางที่บันทึกไว้ในขณะที่คุณเรียกดูแอปพลิเคชันของคุณ เพื่อให้คุณสามารถหาทางกลับไปยังวัตถุได้อย่างง่ายดาย
หากคุณมีปลั๊กอินฉีด forxcode ติดตั้ง Xprobe จะช่วยให้คุณสามารถประเมิน Objective-C หรือ Swift กับอินสแตนซ์ที่เลือกซึ่งคุณมีแหล่งที่มาสำหรับบันทึกหรือแก้ไขแง่มุมใด ๆ ของสถานะของออบเจ็กต์ ณ รันไทม์
ขณะนี้ Xprobe.mm สามารถสแนปช็อตแอปของคุณเป็นไฟล์ html แบบสแตนด์อโลนได้ในกรณีที่เกิดข้อผิดพลาด การดำเนินการนี้จะทำการกวาดล้างและสามารถบันทึกสถานะของแอปของคุณ ณ เวลาที่เกิดข้อผิดพลาดเพื่อการวิเคราะห์ในภายหลัง ไฟล์สแน็ปช็อตตัวอย่างสำหรับโปรเจ็กต์ตัวอย่าง ReactNative "TickTackToe" สามารถดูได้ที่นี่
หากต้องการถ่ายภาพรวม Xprobe.mm ในแอปของคุณและใช้การโทรต่อไปนี้:
[Xprobe snapshot: @" /path/to/snapshot.html.gz " seeds: @[app delegate, rootViewController]];
หากคุณพบปัญหา คุณสามารถเปลี่ยนรูปแบบของชื่อคลาสที่จะไม่บันทึกด้วยอาร์กิวเมนต์รูปแบบ ยกเว้น:(NSString *) เพิ่มเติม ค่าเริ่มต้นสำหรับสิ่งนี้คือ:
@" ^(?:UI|NS((Object|URL|Proxy)$|Text|Layout|Index|.*(Map|Data|Font))|Web|WAK|SwiftObject|XC|IDE|DVT|Xcode3|IB|VK) "
คุณสมบัติที่เหลือจะถูกรีดออกได้ง่ายที่สุดเป็นชุดสัญลักษณ์แสดงหัวข้อย่อย:
คลิกลิงก์ของออบเจ็กต์เพื่อดูเนื้อหา ivar
คลิกลิงก์อีกครั้งเพื่อปิดมุมมองรายละเอียด
คลิกที่ลิงค์ซูเปอร์คลาสเพื่อดูไอวาร์ส
คลิกที่ชื่อ ivar เพื่อรีเฟรชค่าจากแอป
คลิกที่ค่า ivar เพื่อแก้ไขและตั้งค่าในแอป
สามารถดูคุณสมบัติ วิธีการ และโปรโตคอลของคลาสได้
สามารถค้นหารายการวิธีการได้ (รวมถึงการค้นหาวิธีซูเปอร์คลาสด้วย)
ใช้ลิงก์ "ติดตาม" เพื่อเริ่มบันทึกการเรียกไปยังเมธอดบนอินสแตนซ์นั้น
เมื่อต้องการดูวิธีการทั้งหมดที่ติดตามสำหรับวัตถุ คลิกติดตามกับแต่ละคลาส
เอาต์พุตการติดตามสามารถกรองได้โดยใช้นิพจน์ทั่วไป
ลิงก์มุมมองย่อยจะแสดงแผนผังมุมมองย่อยซ้ำๆ ใต้มุมมอง
ลิงก์ "เรนเดอร์" จะจับภาพเมื่อวัตถุอยู่ในมุมมอง
ลิงก์พี่น้องจะแสดงวัตถุทั้งหมดที่พบซึ่งแชร์คลาสของวัตถุ
รีเฟรชรายการวัตถุโดยพิมพ์ Enter ในช่องค้นหาเพื่อบังคับให้กวาดใหม่
การกดปุ่มกราฟจะเปิดมุมมองสรุปของวัตถุที่สำคัญที่สุดและวัตถุ "ชุด" ใดๆ ที่เชื่อมโยงโดยตรงกับวัตถุเหล่านั้นที่นำมาจากการกวาดครั้งล่าสุด
วัตถุจะแสดงเป็นสี่เหลี่ยมจัตุรัสหากเป็นมุมมอง (ตอบสนองต่อ "มุมมองย่อย")
การแสดงกราฟจำเป็นต้องติดตั้ง "Graphviz/dot" บนคอมพิวเตอร์ของคุณ
คลิกที่วัตถุเพื่อดูเนื้อหาปัจจุบันตามที่กล่าวไว้ข้างต้น
การกรองที่แตกต่างกันของออบเจ็กต์ที่จะรวมไว้สามารถนำมาใช้ได้
"ข้อความเคลื่อนไหว" จะติดตามวัตถุโดยแสดงเป็น "สีแดง" เมื่อได้รับข้อความ
สามารถส่งออกกราฟเป็นรูปแบบ Graphviz หรือ .png เพื่อการพิมพ์ได้
อนิจจาการสนับสนุน Swift มีข้อ จำกัด ในขณะนี้เนื่องจาก ivar_getTypeEncoding() ส่งคืน NULL สำหรับฟิลด์ ivar เพื่อป้องกันไม่ให้พวกเขามีส่วนร่วมในการ "กวาด"
Xprobe ทำงานโดยการโหลดบันเดิลในเครื่องจำลองซึ่งเชื่อมต่อกับ Xcode เมื่อโหลด แอปพลิเคชันสร้างรายการโหนดเริ่มต้นที่ Xprobe รู้จักโดยการใช้หมวดหมู่ต่อไปนี้:
@implementation Xprobe (Seeding)
+ ( NSArray *)xprobeSeeds {
UIApplication *app = [UIApplication sharedApplication ];
NSMutableArray *seeds = [ NSMutableArray arrayWithObject: app];
[seeds addObjectsFromArray: [app windows ]];
// support for cocos2d
Class ccDirectorClass = NSClassFromString ( @" CCDirector " );
CCDirector *ccDirector = [ccDirectorClass sharedDirector ];
if ( ccDirector )
[seeds addObject: ccDirector];
return seeds;
}
@end
หรือสำหรับ OSX:
+ ( NSArray *)xprobeSeeds {
NSApplication *app = [ NSApplication sharedApplication ];
NSMutableArray *seeds = [[app windows ] mutableCopy ];
if ( app. delegate )
[seeds insertObject: app.delegate atIndex: 0 ];
return seeds;
}
เมื่อเริ่มต้นแอปแล้ว ให้โทร [Xprobe ConnectTo:"your.ip.address" RetainObjects:YES] เพื่อเชื่อมต่อกับเซิร์ฟเวอร์ TCP ที่ทำงานภายใน Xcode อาร์กิวเมนต์ KeepObjects: ระบุว่าจะเก็บวัตถุที่พบในการกวาดหรือไม่ สิ่งนี้จะทำให้ Xprobe น่าเชื่อถือมากขึ้น แต่จะส่งผลต่อวงจรชีวิตของออบเจ็กต์ในแอปของคุณ หลังจากนี้ ให้เรียก [Xprobe search:@""] เพื่อดำเนินการกวาดเริ่มต้นโดยเริ่มต้นที่ออบเจ็กต์เหล่านี้เพื่อค้นหาออบเจ็กต์รูท แต่ละครั้งที่มีการเรียก "ค้นหา:" หรือตัวกรองคลาสอ็อบเจ็กต์มีการเปลี่ยนแปลง การกวาดจะดำเนินการอีกครั้ง แอปพลิเคชันจะต้องสร้างด้วย Xprobe และ Xtrace{h,mm}
ในยุคสมัยนี้ที่ตัวชี้ "แข็งแกร่ง" และ "อ่อนแอ" ที่สะอาดหมดจด การกวาดดูน่าเชื่อถือมากหากมองเห็นวัตถุด้วยประการใดทางหนึ่ง คลาสดั้งเดิมบางคลาสทำงานได้ไม่ดีนัก และใช้คุณสมบัติ "กำหนด" ซึ่งอาจประกอบด้วยพอยน์เตอร์ไปยังอ็อบเจ็กต์ที่จัดสรรคืน เพื่อหลีกเลี่ยงการกวาดล้าง ivars ของคลาสเหล่านี้ Xprobe มีตัวกรองการแยกซึ่งสามารถแทนที่ได้ (พร้อมคำเตือน) ในหมวดหมู่:
static NSString *swiftPrefix = @" _TtC " ;
@implementation Xprobe (ExclusionOverride)
+ ( BOOL )xprobeExclude:( NSString *)className {
static NSRegularExpression *excluded;
if ( !excluded )
excluded = [ NSRegularExpression xsimpleRegexp: @" ^(_|NS|XC|IDE|DVT|Xcode3|IB|VK|WebHistory) " ];
return [excluded xmatches: className] && ![className hasPrefix: swiftPrefix];
}
@end
การยกเว้นเหล่านี้ทำให้ Xprobe ทำงานภายใน Xcode ได้อย่างหมดจด ซึ่งมีประโยชน์หากคุณเป็นผู้พัฒนาปลั๊กอิน สำหรับข้อเสนอแนะหรือข้อเสนอแนะใด ๆ คุณสามารถติดต่อผู้เขียนบน xprobe ได้ที่ johnholdsworth.com รุ่นหลักจะมีการประกาศบน Twitter @ Injection4Xcode
ด้วย Swift 2.3+ Xprobe จะไม่สามารถสแกน ivars ที่ไม่มีคุณสมบัติได้อีกต่อไป เช่น คลาสที่ไม่ได้รับสืบทอดจาก NSObject
Xprobe.{h,mm} - ฟังก์ชันหลักของ Xprobe ที่จำเป็นสำหรับสแนปช็อต IvarAccess.h - รูทีนที่จำเป็นสำหรับการเข้าถึงคลาส ivars ตามชื่อ Xprobe+Service.mm - บริการเสริมแบบโต้ตอบที่เชื่อมต่อกับ Xcode
ลิขสิทธิ์ (c) 2014-5 จอห์น โฮลส์เวิร์ธ ได้รับอนุญาตให้ดาวน์โหลด ดัดแปลง และใช้งานใดๆ ในระหว่างการพัฒนาแอปพลิเคชัน Objectice-C การแจกจ่ายซ้ำสามารถทำได้ผ่าน GitHub สาธารณะเท่านั้น อย่างไรก็ตาม รวมถึงประกาศเกี่ยวกับลิขสิทธิ์นี้ด้วย สำหรับการแจกจ่ายแบบไบนารีด้วยแอปของคุณ โปรดติดต่อ!
รุ่นนี้มีการแก้ไขเล็กน้อยของไลบรารี canviz ที่ยอดเยี่ยมเพื่อเรนเดอร์ไฟล์ "dot" ในพื้นที่ทำงาน HTML ซึ่งอยู่ภายใต้ใบอนุญาต MIT การเปลี่ยนแปลงจะต้องส่งผ่าน ID ของโหนดไปยังแท็กป้ายกำกับโหนด (บรรทัด 212) เพื่อย้อนกลับการเรนเดอร์ของโหนดและบรรทัดที่เชื่อมโยงโหนดเหล่านั้น (บรรทัด 406) และเพื่อจัดเก็บเส้นทางขอบเพื่อให้สามารถใส่สีได้ (บรรทัด 66 และ 303) ใน "canviz-0.1/canviz.js"
ขณะนี้ยังมีโปรแกรมแก้ไข CodeMirror JavaScript สำหรับโค้ดที่จะประเมินโดยใช้การแทรกภายใต้ใบอนุญาต MIT
ซอฟต์แวร์นี้มีให้ "ตามที่เป็น" โดยไม่มีการรับประกันใดๆ ทั้งโดยชัดแจ้งหรือโดยนัย ซึ่งรวมถึงแต่ไม่จำกัดเพียงการรับประกันความสามารถในการค้าขาย ความเหมาะสมสำหรับวัตถุประสงค์เฉพาะ และการไม่ละเมิด ไม่ว่าในกรณีใดผู้เขียนหรือผู้ถือลิขสิทธิ์จะต้องรับผิดต่อการเรียกร้องค่าเสียหายหรือความรับผิดอื่นใดไม่ว่าในการกระทำของสัญญาการละเมิดหรืออย่างอื่นที่เกิดขึ้นจากหรือเกี่ยวข้องกับซอฟต์แวร์หรือการใช้งานหรือข้อตกลงอื่น ๆ ใน ซอฟต์แวร์.