2012-10-25 33 views
8

Tôi nghĩ rằng tôi gần gũi với sự hiểu biết how Mono GC and ObjC ref counting live together.Tại sao MonoTouch GC không thể xử lý các đối tượng được quản lý với refcount> 1?

Cách hoạt động là khi một đối tượng gốc có số tham chiếu là 1, chúng tôi không ngăn trường hợp được quản lý thu thập rác thải. Ngay khi số lượng tham chiếu tăng lên trên 1, chúng tôi ngăn chặn trường hợp được quản lý thu thập rác thải.

Điều này là do đối tượng được quản lý có thể chứa trạng thái người dùng. MonoTouch biết rằng cá thể không thể chứa bất kỳ trạng thái nào, vì vậy ngay sau khi không có mã được quản lý nào có tham chiếu đến cá thể được quản lý, GC có thể thu thập nó. Nếu một cá thể được quản lý được yêu cầu ở giai đoạn sau, chúng ta chỉ cần tạo một phiên bản mới.

Vì vậy, nếu tôi có thể tạo một CustomButton mà thừa hưởng UIButton, thêm nó như subview để View của tôi, chúng ta hãy phiếu tham khảo được quản lý ra khỏi phạm vi và sau đó chạy GC, này được quản lýCustomButton vẫn sẽ không đủ điều kiện cho bộ sưu tập .

Tại sao nó không thể được thu thập? Tất nhiên nó có thể được quản lý nhà nước như tài sản, nhưng nếu không có liên kết đến nó từ các đối tượng quản lý, những người quan tâm về trạng thái này? Nó cũng có thể biến mất, tại sao phải không?

Tôi đang nghĩ đến một lý do có thể: đăng ký CustomButton sự kiện sẽ không giữ cho nó tồn tại cho GC để khi đối tượng được thu thập, các sự kiện sẽ ngừng kích hoạt. Điều này có lẽ sẽ dẫn đến hành vi bất ngờ.

Điều này có đúng không? Có lý do nào khác để giữ cho đối tượng được quản lý còn sống ngay cả khi không có ai liên kết nó?

Trả lời

6

Tại sao nó không thể được thu thập? Tất nhiên nó có thể đã quản lý nhà nước như tài sản, nhưng nếu không có liên kết đến nó từ các đối tượng quản lý, những người quan tâm về tình trạng này? Nó cũng có thể biến mất, tại sao phải không?

Mã gốc có thể có tham chiếu đến đối tượng, điều này có thể khiến đối tượng này xuất hiện lại mã được quản lý sau.

Tôi tin rằng một mẫu mã sẽ minh họa những gì sẽ xảy ra:

class MyView : UIView { 
    public string ImportantSecret; 
} 

class AppDelegate : UIApplicationDelegate { 
    UIViewController vc; 
    public override bool FinishedLaunching (UIApplication app, 
              NSDictionary options) 
    { 
     var myView = new MyView(); 
     myView.ImportantSecret = "MonoTouchRocks"; 

     vc = new UIViewController(); 
     vc.View = new UIView(); 
     vc.View.AddSubView (myView); 

     // When this method returns the only place where myView is referenced 
     // is from inside the *native* Subviews collection. 

     BeginInvokeOnMainThread (() => 
     { 
      Console.WriteLine (((MyView) vc.Subviews [0]).ImportantSecret); 
      // If the MyView instance was garbage collected and recreated 
      // automatically at this point, ImportantSecret would be null. 
     }); 
    } 
} 

Chú ý: mã này chỉ là để minh họa cho lý do tại sao GC không thể thu thập đối tượng quản lý mà chưa có nhà nước. Mẫu cụ thể này thực sự sẽ không quên bí mật quan trọng, vì mảng Subviews được lưu trữ tự động trong mã được quản lý - nhưng điều này thường không đúng.

+0

Cuối cùng tôi đã hiểu! Hỗ trợ của bạn ở đây là không thể thiếu. –

+1

Tôi yêu hai câu hỏi của bạn và câu trả lời tuyệt vời của Rolf - chỉ cần học một cái gì đó mới :-) –

+0

Tôi đã chơi xung quanh với điều này. Điều gì sẽ xảy ra nếu biến myView được tạo bên trong một khối sử dụng? Công cụ công cụ chỉ ra rằng các trường hợp được phát hành. Nó cảm thấy rất khó xử, nhưng tôi không thể nhận dạng và các vấn đề trong hành vi của mã. Suy nghĩ? @rolf –

Các vấn đề liên quan