iOS 視圖:重繪與UIScrollView(內容根據iOS編程編寫)

来源:http://www.cnblogs.com/wang-com/archive/2016/09/17/5870304.html
-Advertisement-
Play Games

我們繼續之前的 Hypnosister 應用,當用戶開始觸摸的時候,圓形的顏色會改變。 首先,在 JXHypnosisView 頭文件中聲明一個屬性,用來表示圓形的顏色。 加入的三行代碼稱為 JXHypnosisView 的類擴展。類擴展中聲明一個顏色屬性。 在 JXHypnosisView 實現文 ...


  我們繼續之前的 Hypnosister 應用,當用戶開始觸摸的時候,圓形的顏色會改變。

  首先,在 JXHypnosisView 頭文件中聲明一個屬性,用來表示圓形的顏色。

#import "JXHypnosisView.h"

@interface JXHypnosisView ()

/** 顏色 */
@property (nonatomic,strong) UIColor * circleColor;

@end

@implementation JXHypnosisView

- (instancetype)initWithFrame:(CGRect)frame {
    self = [super initWithFrame:frame];
    if (self) {
        // 設置 JXHypnosisView 對象的背景顏色為透明
        self.backgroundColor = [UIColor clearColor];
    }
    return self;
}

- (void)drawRect:(CGRect)rect {
    
    CGRect bounds = self.bounds;

    // 根據bounds計算中心點
    CGPoint center;
    center.x = bounds.origin.x + bounds.size.width / 2.0;
    center.y = bounds.origin.y + bounds.size.height / 2.0;
    
    // 是最外層圓形成為視圖的外接圓
    float maxRadius = hypotf(bounds.size.width, bounds.size.height) / 2.0;
    
    UIBezierPath * path = [[UIBezierPath alloc] init];

    for (float currentRadius = maxRadius; currentRadius > 0; currentRadius -= 20) {
        
        // 用來設置繪製起始位置
        [path moveToPoint:CGPointMake(center.x + currentRadius, center.y)];
        
        [path addArcWithCenter:center
                        radius:currentRadius
                    startAngle:0.0
                      endAngle:M_PI * 2.0
                     clockwise:YES];
    }
    
    // 設置線條寬度為 10 點
    path.lineWidth = 10;
    
    // 設置繪製顏色為灰色
    [[UIColor lightGrayColor] setStroke];
    
    // 繪製路徑
    [path stroke];
    
    
    // 創建UIImage對象
    UIImage * logoImage = [UIImage imageNamed:@"train"];
    // 繪製圖像
    [logoImage drawInRect:bounds];
    
}

@end

  加入的三行代碼稱為  JXHypnosisView 的類擴展。類擴展中聲明一個顏色屬性。

  在  JXHypnosisView 實現文件中我們可以為顏色屬性設置一個預設值

#import "JXHypnosisView.h"

@interface JXHypnosisView ()

/** 顏色 */
@property (nonatomic,strong) UIColor * circleColor;

@end

@implementation JXHypnosisView

- (instancetype)initWithFrame:(CGRect)frame {
    self = [super initWithFrame:frame];
    if (self) {
        // 設置 JXHypnosisView 對象的背景顏色為透明
        self.backgroundColor = [UIColor clearColor];
        self.circleColor = [UIColor lightGrayColor];
    }
    return self;
}

- (void)drawRect:(CGRect)rect {
    
    CGRect bounds = self.bounds;

    // 根據bounds計算中心點
    CGPoint center;
    center.x = bounds.origin.x + bounds.size.width / 2.0;
    center.y = bounds.origin.y + bounds.size.height / 2.0;
    
    // 是最外層圓形成為視圖的外接圓
    float maxRadius = hypotf(bounds.size.width, bounds.size.height) / 2.0;
    
    UIBezierPath * path = [[UIBezierPath alloc] init];

    for (float currentRadius = maxRadius; currentRadius > 0; currentRadius -= 20) {
        
        // 用來設置繪製起始位置
        [path moveToPoint:CGPointMake(center.x + currentRadius, center.y)];
        
        [path addArcWithCenter:center
                        radius:currentRadius
                    startAngle:0.0
                      endAngle:M_PI * 2.0
                     clockwise:YES];
    }
    
    // 設置線條寬度為 10 點
    path.lineWidth = 10;
    
    // 設置繪製顏色為灰色
    [[UIColor lightGrayColor] setStroke];
    
    // 繪製路徑
    [path stroke];
    
    
    // 創建UIImage對象
    UIImage * logoImage = [UIImage imageNamed:@"train"];
    // 繪製圖像
    [logoImage drawInRect:bounds];

}

@end

  在  drawRect: 方法中修改設置線條顏色的代碼。使用 circleColor 作為線條顏色

#import "JXHypnosisView.h"

@interface JXHypnosisView ()

/** 顏色 */
@property (nonatomic,strong) UIColor * circleColor;

@end

@implementation JXHypnosisView

- (instancetype)initWithFrame:(CGRect)frame {
    self = [super initWithFrame:frame];
    if (self) {
        // 設置 JXHypnosisView 對象的背景顏色為透明
        self.backgroundColor = [UIColor clearColor];
        self.circleColor = [UIColor lightGrayColor];
    }
    return self;
}

- (void)drawRect:(CGRect)rect {
    
    CGRect bounds = self.bounds;

    // 根據bounds計算中心點
    CGPoint center;
    center.x = bounds.origin.x + bounds.size.width / 2.0;
    center.y = bounds.origin.y + bounds.size.height / 2.0;
    
    // 是最外層圓形成為視圖的外接圓
    float maxRadius = hypotf(bounds.size.width, bounds.size.height) / 2.0;
    
    UIBezierPath * path = [[UIBezierPath alloc] init];

    for (float currentRadius = maxRadius; currentRadius > 0; currentRadius -= 20) {
        
        // 用來設置繪製起始位置
        [path moveToPoint:CGPointMake(center.x + currentRadius, center.y)];
        
        [path addArcWithCenter:center
                        radius:currentRadius
                    startAngle:0.0
                      endAngle:M_PI * 2.0
                     clockwise:YES];
    }
    
    // 設置線條寬度為 10 點
    path.lineWidth = 10;
    
    // 設置繪製顏色為灰色
    [[UIColor lightGrayColor] setStroke];
    [self.circleColor setStroke];
    // 繪製路徑
    [path stroke];
    
    
    // 創建UIImage對象
    UIImage * logoImage = [UIImage imageNamed:@"train"];
    // 繪製圖像
    [logoImage drawInRect:bounds];

}

@end

  構建並運行,結果應該跟之前一樣。下一步我們來編寫視圖被觸摸的時候改變圓形顏色的代碼:

  當用戶觸摸的時候會收到一個方法  touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event ,現在我們只需要將之覆蓋

#import "JXHypnosisView.h"

@interface JXHypnosisView ()

/** 顏色 */
@property (nonatomic,strong) UIColor * circleColor;

@end

@implementation JXHypnosisView

- (instancetype)initWithFrame:(CGRect)frame {
    self = [super initWithFrame:frame];
    if (self) {
        // 設置 JXHypnosisView 對象的背景顏色為透明
        self.backgroundColor = [UIColor clearColor];
        self.circleColor = [UIColor lightGrayColor];
    }
    return self;
}

- (void)drawRect:(CGRect)rect {
    
    CGRect bounds = self.bounds;

    // 根據bounds計算中心點
    CGPoint center;
    center.x = bounds.origin.x + bounds.size.width / 2.0;
    center.y = bounds.origin.y + bounds.size.height / 2.0;
    
    // 是最外層圓形成為視圖的外接圓
    float maxRadius = hypotf(bounds.size.width, bounds.size.height) / 2.0;
    
    UIBezierPath * path = [[UIBezierPath alloc] init];

    for (float currentRadius = maxRadius; currentRadius > 0; currentRadius -= 20) {
        
        // 用來設置繪製起始位置
        [path moveToPoint:CGPointMake(center.x + currentRadius, center.y)];
        
        [path addArcWithCenter:center
                        radius:currentRadius
                    startAngle:0.0
                      endAngle:M_PI * 2.0
                     clockwise:YES];
    }
    
    // 設置線條寬度為 10 點
    path.lineWidth = 10;
    
    // 設置繪製顏色為灰色
    [[UIColor lightGrayColor] setStroke];
    [self.circleColor setStroke];
    // 繪製路徑
    [path stroke];
    
    
    // 創建UIImage對象
    UIImage * logoImage = [UIImage imageNamed:@"train"];
    // 繪製圖像
    [logoImage drawInRect:bounds];

}

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    
    // 取三個 0~1 之間的數字
    float red = (arc4random() % 100) /100.0;
    float green = (arc4random() % 100) /100.0;
    float blue = (arc4random() % 100) /100.0;
    
    UIColor * randomColor = [UIColor colorWithRed:red
                                            green:green
                                             blue:blue
                                            alpha:1.0];
    
    self.circleColor = randomColor;
}
@end

   構建並運行,我們發現好像程式並沒有改變任何顏色,這是因為 JXHypnosisView 並沒有重繪自己。

  • 運行迴圈和重繪視圖

  iOS應用啟動時會開始一個運行迴圈(run loop).運行迴圈的工作是監聽事件,例如觸摸,當事件發生時,運行迴圈就會為相應的事件找到合適的處理方法。這些處理方法會調用其他方法而這些其他方法就又會調用更多其他方法。這樣子,只有當這些所有方法執行完畢的時候,控制權才會再次回到運行迴圈。

  當應用將控制權交還給運行迴圈時,運行迴圈會首先檢查是否有等待重繪的視圖(即在當前迴圈收到過 setNeedsDisplay 消息的視圖),然後向所有等待重繪的視圖發送 drawRect: 消息,最後視圖層次結構中所有視圖的圖層會再次組合成一幅完整的圖像並繪製到屏幕上。

  iOS做了兩個方面優化來保證用戶界面的流暢性---不重繪顯示的內容沒有改變的視圖;在每次事件處理中期中只發送一次 drawRect 消息。在事件處理周期中,視圖的屬性可能會發生多次改變,如果視圖在每次屬性改變的時候都要重繪自己,就會減慢界面的響應速度。想法,iOS會在運行迴圈的最後階段集中處理所有需要重繪的視圖,尤其是對於屬性發生多次改變的視圖,在每次事件處理周期中只重繪一次。

  在本應用中,首先可以肯定的是,我們的觸摸處理的方法已經正確捕獲了觸摸事件,但是雖然運行迴圈在執行完 touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event 後再次獲得了控制權,但是並沒有向 JXHypnosisView 發送 drawRect 消息。

  為了標記視圖需要重繪,必須向其發送 setNeedsDisplay 消息。iOS SDK 中提供的視圖對象會自動在顯示的內容發生改變時向自身發送 setNeedsDisplay 消息,以UILabel 對象為例,在某個 UILabel 對象收到 setText:消息後,就會將自身標記為要重繪(因為其所顯示的文字內容改變了,所以必須將自己重繪到圖層上)。而對自定義的 UIView 子類,必須手動向其發送  setNeedsDisplay 消息。

  在 JXHypnosisView.m 中,為 circleColor 屬性實現自定義的存方法,當 circleColor 改變時,向視圖發送  setNeedsDisplay 消息

#import "JXHypnosisView.h"

@interface JXHypnosisView ()

/** 顏色 */
@property (nonatomic,strong) UIColor * circleColor;

@end

@implementation JXHypnosisView

- (instancetype)initWithFrame:(CGRect)frame {
    self = [super initWithFrame:frame];
    if (self) {
        // 設置 JXHypnosisView 對象的背景顏色為透明
        self.backgroundColor = [UIColor clearColor];
        self.circleColor = [UIColor lightGrayColor];
    }
    return self;
}

- (void)drawRect:(CGRect)rect {
    
    CGRect bounds = self.bounds;

    // 根據bounds計算中心點
    CGPoint center;
    center.x = bounds.origin.x + bounds.size.width / 2.0;
    center.y = bounds.origin.y + bounds.size.height / 2.0;
    
    // 是最外層圓形成為視圖的外接圓
    float maxRadius = hypotf(bounds.size.width, bounds.size.height) / 2.0;
    
    UIBezierPath * path = [[UIBezierPath alloc] init];

    for (float currentRadius = maxRadius; currentRadius > 0; currentRadius -= 20) {
        
        // 用來設置繪製起始位置
        [path moveToPoint:CGPointMake(center.x + currentRadius, center.y)];
        
        [path addArcWithCenter:center
                        radius:currentRadius
                    startAngle:0.0
                      endAngle:M_PI * 2.0
                     clockwise:YES];
    }
    
    // 設置線條寬度為 10 點
    path.lineWidth = 10;
    
    // 設置繪製顏色為灰色
    [[UIColor lightGrayColor] setStroke];
    [self.circleColor setStroke];
    // 繪製路徑
    [path stroke];
    
    
    // 創建UIImage對象
    UIImage * logoImage = [UIImage imageNamed:@"train"];
    // 繪製圖像
    [logoImage drawInRect:bounds];

}

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    
    // 取三個 0~1 之間的數字
    float red = (arc4random() % 100) /100.0;
    float green = (arc4random() % 100) /100.0;
    float blue = (arc4random() % 100) /100.0;
    
    UIColor * randomColor = [UIColor colorWithRed:red
                                            green:green
                                             blue:blue
                                            alpha:1.0];
    
    self.circleColor = randomColor;
}

// 為屬性實現自定義的存方法
- (void)setCircleColor:(UIColor *)circleColor {
    _circleColor = circleColor;
    [self setNeedsDisplay];
}
@end

  再次構建運行,就可以實現我們的需求了。

  還有一種優化方法:只重繪視圖的某一區域。可以通過向視圖發送 setNeedsDisplayInRect: 消息標記視圖的某一區域要重繪。當視圖收到  drawRect 消息時, setNeedsDisplayInRect: 會將 CGRect 類型的參數傳遞給  drawRect: 重繪視圖的指定區域。但是通常我們不推薦這樣做。

 

  • 類擴展

  現在我們討論將 circleColor 屬性生命在 JXHypnosisView 的類擴展中和聲明在頭文件中的區別。 

  頭文件是一個類的 “用戶手冊” ,其他類可以可以通過頭文件知道該類的工能和使用方法。使用頭文件的目的是向其他類公開該類聲明的屬性和方法。也就是說頭文件中聲明的屬性和方法對其他類是可見的。

  但是,並不是每一個屬性或者方法都要想其他類公開。只會在類的內部使用的屬性和方法應當聲明在類擴展中。circleColor 屬性只會被  JXHypnosisView 使用,其他類不需要使用該屬性,因此會被聲明在類擴展中。

  子類同樣無法訪問父類在理擴展中聲明的屬性和方法。有時候需要讓其他開發者瞭解類的某些內部屬性和方法,以便更好的理解類的工作原理和使用方法。可以在另一個文件中聲明類擴展,並將該文件導入類的實現文件中。

 

  • 使用 UIScrollView

  接下來我們繼續為  Hypnosister  應用添加一個 UIScrollView 對象,使其成為應用視窗的子視圖,然後再將  JXHypnosisView  作為子視圖加入 UIScrollView 對象。個對象之間的關係如圖

  通常情況下,UIScrollView 對象適用於那些尺寸大於屏幕的視圖。當某個視圖是 UIScrollView 對象的子視圖的時候,該對象會畫出該視圖的某塊區域(形狀為矩形)。當用戶按住這塊矩形區域並拖動的時候,UIScrollView 對昂會改變該矩形所顯示的子視圖區域。我們可以將 UIScrollView 對象看成是鏡頭,而其子視圖是拍攝的場景。這裡移動的是 “鏡頭” ,而不是 “景觀”。 UIScrollView 對象的尺寸就是這個 “鏡頭”的尺寸,而其能夠拍攝的範圍是由其屬性  contentsize 決定的。通常情況下 contentsize 的數值就是子視圖的尺寸。

  UIScrollView 是 UIView 的子類,同樣可以使用  initWithFrame 消息初始化,還可以將其作為子視圖添加到別的視圖中。

  在  ViewController.m 中,創建一個有著超大尺寸的  JXHypnosisView  對象,並將其加入到一個 UIScrollView 對象,然後將這個對象添加到視圖上。

#import "ViewController.h"
#import "JXHypnosisView.h"

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    // 創建 CGRect 結構
  CGRect rect = CGRectMake(100, 200, 200, 300);

    // 創建視圖
    JXHypnosisView * firstView = [[JXHypnosisView alloc] initWithFrame:rect];


// 創建兩個 CGRect 結構分別作為 UIScrollView 對象和 JXHypnosisView 對象的 frame CGRect screenRect = self.view.bounds; CGRect bigRect = screenRect; bigRect.size.width *= 2.0; bigRect.size.height *= 2.0; // 創建一個 UIScrollView 對象,將其尺寸設置為當前視圖視窗大小 UIScrollView * scrollView = [[UIScrollView alloc] initWithFrame:screenRect]; [self.view addSubview:scrollView]; // 創建一個有著超級大尺寸的 JXHypnosisView 對象並將其加入 UIScrollView 對象 JXHypnosisView * hypnosisView = [[JXHypnosisView alloc] initWithFrame:bigRect]; [scrollView addSubview:hypnosisView]; // 告訴 UIScrollView 對象 “取景”範圍有多大 scrollView.contentSize = bigRect.size; // 將視圖添加到控制器View上
[self.view addSubview:firstView]; } @end

  構建並運行,可以上,下,左右來拖動查看超大的尺寸

  

  拖動與分頁

  UIScrollView 對象還可以滑動顯示所有加入 UIScrollView 對象的子視圖

  在  ViewController.m 中,將  JXHypnosisView  對象的尺寸改回與屏幕的尺寸相同,然後再創建一個  JXHypnosisView 對象,將其尺寸也設置為與屏幕尺寸相同並加入 UIScrollView 對象。此外,還要將 UIScrollView 對象的  contentSize 的寬度設置為屏幕寬度的2倍,高度不變

#import "ViewController.h"
#import "JXHypnosisView.h"

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    // 創建兩個 CGRect 結構分別作為 UIScrollView 對象和 JXHypnosisView 對象的 frame
    CGRect screenRect = self.view.bounds;
    CGRect bigRect = screenRect;
    bigRect.size.width *= 2.0;
    bigRect.size.height *= 2.0;
    
    // 創建一個 UIScrollView 對象,將其尺寸設置為當前視圖視窗大小
    UIScrollView * scrollView = [[UIScrollView alloc] initWithFrame:screenRect];
    [self.view addSubview:scrollView];
    
    // 創建一個有著超級大尺寸的 JXHypnosisView 對象並將其加入 UIScrollView 對象
    JXHypnosisView * hypnosisView = [[JXHypnosisView alloc] initWithFrame:bigRect];
    [scrollView addSubview:hypnosisView];
    
    // 創建一個大小與屏幕相同的 JXHypnosisView 對象並將其加入 UIScrollView 對象
    JXHypnosisView * hypnosisView = [[JXHypnosisView alloc] initWithFrame:screenRect];
    [scrollView addSubview:hypnosisView];
    
    // 創建第二個大小與屏幕相同的 JXHypnosisView 對象並放置在第一個 JXHypnosisView 對象的右側,使其剛好移出到屏幕外
    screenRect.origin.x += screenRect.size.width;
    JXHypnosisView * anotherView = [[JXHypnosisView alloc] initWithFrame:screenRect];
    [scrollView addSubview:anotherView];
    
    // 告訴 UIScrollView 對象 “取景”範圍有多大
    scrollView.contentSize = bigRect.size;

    
}

@end

  構建並運行,拖動屏幕會發現有兩個  JXHypnosisView 對象

  


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • bootstrap-table是一個基於Bootstrap風格的強大的表格插件神器,官網:http://bootstrap-table.wenzhixin.net.cn/zh-cn/ 這裡列出遇到的一個小問題:Bootstrap Table表格一直載入不了數據。 我使用訪問遠程地址返回的json數據 ...
  • 懶實例化-一個服務只有當程式的組件用到它的時候才進行實例化; 單例模式-每個依賴服務的組件,都是獲得服務工廠生成單個實例的引用。服務是一個單例對象或函數,對外提供特定的功能。 ...
  • ...
  • 通過DOM樹可以可容易的訪問到html文檔中的所有元素 例如向上訪問父輩的元素有以下方法 1.parent()方法可以得到所定元素的直接父元素 $("span").parent();得到<span>元素的直接父元素 2.parents()方法得到給定元素的所有父元素 $("span").parent ...
  • Cleave.js 有一個簡單的目的:幫助你自動格式輸入的文本內容。 這個想法是提供一個簡單的方法來格式化您的輸入數據以增加輸入欄位的可讀性。通過使用這個庫,您不需要編寫任何正則表達式來控制輸入文本的格式。然而,這並不意味著取代任何驗證或掩碼庫,你仍應在後端驗證數據。它支持信用卡號碼、電話號碼格式(... ...
  • 2016年9月7日,蘋果發佈iOS 10。2016年9月14日,全新的操作系統iOS 10將正式上線。 作為開發者,如何適配iOS10呢? 1.Notification(通知) 自從Notification被引入之後,蘋果就不斷的更新優化,但這些更新優化只是小打小鬧,直至現在iOS 10開始真正的進 ...
  • 本篇博客以微信為例,給微信脫殼。"砸殼"在iOS逆向工程中是經常做的一件事情,,因為從AppStore直接下載安裝的App是加殼的,其實就是經過加密的,這個“砸殼”的過程就是一個解密的過程。未砸殼的App是無法在Class-dump、Hopper等工具中使用的。所以我們要將App進行砸殼處理。在An ...
  • App Store: 天的故事 行距大果然看著舒服些 1. UI調整,細節優化 App Store: 天的故事 ...
一周排行
    -Advertisement-
    Play Games
  • 示例項目結構 在 Visual Studio 中創建一個 WinForms 應用程式後,項目結構如下所示: MyWinFormsApp/ │ ├───Properties/ │ └───Settings.settings │ ├───bin/ │ ├───Debug/ │ └───Release/ ...
  • [STAThread] 特性用於需要與 COM 組件交互的應用程式,尤其是依賴單線程模型(如 Windows Forms 應用程式)的組件。在 STA 模式下,線程擁有自己的消息迴圈,這對於處理用戶界面和某些 COM 組件是必要的。 [STAThread] static void Main(stri ...
  • 在WinForm中使用全局異常捕獲處理 在WinForm應用程式中,全局異常捕獲是確保程式穩定性的關鍵。通過在Program類的Main方法中設置全局異常處理,可以有效地捕獲並處理未預見的異常,從而避免程式崩潰。 註冊全局異常事件 [STAThread] static void Main() { / ...
  • 前言 給大家推薦一款開源的 Winform 控制項庫,可以幫助我們開發更加美觀、漂亮的 WinForm 界面。 項目介紹 SunnyUI.NET 是一個基於 .NET Framework 4.0+、.NET 6、.NET 7 和 .NET 8 的 WinForm 開源控制項庫,同時也提供了工具類庫、擴展 ...
  • 說明 該文章是屬於OverallAuth2.0系列文章,每周更新一篇該系列文章(從0到1完成系統開發)。 該系統文章,我會儘量說的非常詳細,做到不管新手、老手都能看懂。 說明:OverallAuth2.0 是一個簡單、易懂、功能強大的許可權+可視化流程管理系統。 有興趣的朋友,請關註我吧(*^▽^*) ...
  • 一、下載安裝 1.下載git 必須先下載並安裝git,再TortoiseGit下載安裝 git安裝參考教程:https://blog.csdn.net/mukes/article/details/115693833 2.TortoiseGit下載與安裝 TortoiseGit,Git客戶端,32/6 ...
  • 前言 在項目開發過程中,理解數據結構和演算法如同掌握蓋房子的秘訣。演算法不僅能幫助我們編寫高效、優質的代碼,還能解決項目中遇到的各種難題。 給大家推薦一個支持C#的開源免費、新手友好的數據結構與演算法入門教程:Hello演算法。 項目介紹 《Hello Algo》是一本開源免費、新手友好的數據結構與演算法入門 ...
  • 1.生成單個Proto.bat內容 @rem Copyright 2016, Google Inc. @rem All rights reserved. @rem @rem Redistribution and use in source and binary forms, with or with ...
  • 一:背景 1. 講故事 前段時間有位朋友找到我,說他的窗體程式在客戶這邊出現了卡死,讓我幫忙看下怎麼回事?dump也生成了,既然有dump了那就上 windbg 分析吧。 二:WinDbg 分析 1. 為什麼會卡死 窗體程式的卡死,入口門檻很低,後續往下分析就不一定了,不管怎麼說先用 !clrsta ...
  • 前言 人工智慧時代,人臉識別技術已成為安全驗證、身份識別和用戶交互的關鍵工具。 給大家推薦一款.NET 開源提供了強大的人臉識別 API,工具不僅易於集成,還具備高效處理能力。 本文將介紹一款如何利用這些API,為我們的項目添加智能識別的亮點。 項目介紹 GitHub 上擁有 1.2k 星標的 C# ...