2009-07-31 37 views
33

Vì vậy, tôi nghĩ rằng tôi đã có tất cả những câu hỏi này tất cả đã tìm ra. Sau đó, tất cả của một đột ngột tôi nhận được một lỗi (một vụ tai nạn) Tôi không thể tìm ra. Sau đó, sau khi nghiên cứu để khắc phục sự cố, tôi nhận thấy mọi thứ mà tôi nghĩ rằng tôi biết về những khu vực quan trọng này có phần sai.Phát hành, Dealloc và tham chiếu Tự

Dưới đây là 8 câu hỏi Tôi chỉ muốn quay ra ngoài với hy vọng có ai đó trả lời - câu trả lời cho những điều này sẽ giúp tôi hiểu rõ về sự theo dõi của mình. Cảm ơn trước!

Q1) Có được phép phát hành trên một đối tượng nếu tham chiếu đó là không? Điều này sẽ vô hại, phải không?

Q2) Bạn có thể gọi phát hành trên một đối tượng nếu tham chiếu đó đã được phát hành và là số tham chiếu 0 không?

Q3) Có cần thiết đặt tham chiếu về nil SAU KHI phát hành không? Điều gì sẽ xảy ra nếu bạn không đặt nó thành nil?

Q4) Thực sự có sự khác biệt giữa nil và NULL hay chỉ là một điều ngữ nghĩa để giúp người đọc/nhà phát triển biết loại đối tượng chỉ bằng cách liếc qua nó?

Q5) Sử dụng các thuộc tính YÊU CẦU sử dụng con trỏ 'Tự'?

Q6) Sử dụng các biến mẫu yêu cầu con trỏ 'Tự' KHÔNG được sử dụng?

Q7) Khi nào tôi muốn sử dụng biến mẫu thay vì thuộc tính của nó? Tôi tưởng tượng các thành viên dữ liệu loại giá trị được chấp nhận vì họ không phát hành và duy trì sự tham gia.

Q8) Có cần phải gọi dealloc của đối tượng từ bên trong hàm dealloc không? Trong nhiều ví dụ tôi đã thấy Bản phát hành được gọi, nhưng không phải là Dealloc - có phải là các hướng dẫn như vậy không chính xác không?

+0

Đẹp q.Tôi chỉ tìm thấy một số câu hỏi mới mà tôi thậm chí không biết tôi muốn trả lời. – typeoneerror

Trả lời

11

Có lẽ bạn nên chia câu hỏi này thành nhiều câu hỏi khác nhau, nhưng tôi sẽ cắn.

  1. Có, bất kỳ thư nào được gửi đến nil đều là no-op.
  2. Không. Một đối tượng có số lượng ref là 0, hoặc sắp bị hủy và mọi thư được gửi đến sẽ gây ra sự cố hoặc tốt nhất là ngoại lệ.
  3. Tùy thuộc vào tình huống. Nếu bạn đang phát hành mọi thứ trong -dealloc, thì có thể không. Nếu nó là một đối tượng được dàn vào một phương pháp cụ thể, thì có lẽ không. Nếu nó là một cây ngà được tái sử dụng, tôi sẽ nói có. Trong hai trường hợp đầu tiên, sẽ không có gì xảy ra nếu bạn không đặt con trỏ thành nil, vì bạn thường không thể truy cập các con trỏ đó nữa. Tuy nhiên, trong trường hợp cuối cùng, bạn vẫn có thể truy cập con trỏ, trỏ đến bộ nhớ được phân bổ lại. Nếu bạn gửi một tin nhắn hoặc cố gắng dereference nó, ứng dụng của bạn sẽ sụp đổ.
  4. Cả hai đều bằng 0. Theo quy ước nil được sử dụng cho con trỏ đối tượng và NULL được sử dụng cho bất kỳ con trỏ nào khác, nhưng trộn chúng sẽ không gây ra bất kỳ sự cố nào.
  5. Nếu bạn muốn gọi trình khởi động/thiết lập thuộc tính, thì có. Nếu bạn muốn truy cập ivar nó đóng gói trực tiếp (không phổ biến), không.
  6. Không, bạn có thể truy cập các biến mẫu bằng cách sử dụng cú pháp self->ivar. Trong thực tế, khi bạn chỉ nhập ivar, trình biên dịch ngầm thêm thông báo hội nghị self->.
  7. Không chắc chắn ý của bạn ở đây.
  8. Lần duy nhất bạn nên gọi -dealloc là khi gọi [super dealloc]; trong các phương thức -dealloc của riêng bạn. Đối với bất kỳ đối tượng nào khác, bạn nên luôn gọi số -release.
+0

Tại (2) NSZombieEnabled nên được đề cập. Nó làm cho vấn đề phân bổ gỡ lỗi dễ dàng. – diciu

+0

"dễ" là một từ mạnh mẽ! Tôi sẽ nói "dễ hơn". –

19

A1) [nil release] là tốt (sẽ không làm bất cứ điều gì)

A2) Số Đừng chạm vào đối tượng sau khi họ đã được deallocated. Chúng sẽ được đặt thành 0 sau khi chúng được giải phóng.

A3) Không cần thiết đặt con trỏ được giải phóng thành 0, nhưng bạn nhận được con trỏ lơ lửng (tức là bạn không thể biết một đối tượng có hợp lệ hay không). Việc đặt thuộc tính thành nil thường được sử dụng để giải phóng ivar cơ bản, do đó việc không thực hiện điều này có thể gây ra rò rỉ bộ nhớ

A4) và cả hai đều bằng không, vì vậy về mặt kỹ thuật giống nhau.

A5) Vâng, bạn phải sử dụng self.someProperty đối với tài sản, cũng giống như bạn sẽ sử dụng [self someProperty] nếu nó chỉ là một phương pháp

A6) tự bản chất là một cấu trúc, vì vậy bạn có thể truy cập ivars như vậy: self->someIvar. Không cần phải, mặc dù.

A7) Khi bạn không muốn chạy các phương thức setter/getter vì bất kỳ lý do gì. Tôi sử dụng nó một cách ocassionally khi setter không cho phép các giá trị nil, và tôi cần phải giải phóng biến số

A8) dealloc được gọi tự động khi phát hành được gọi là số lần chính xác. Bạn không bao giờ nên gọi trực tiếp cho dealloc (ngoại trừ [super dealloc])

+1

Tôi đang nhầm lẫn về # 5. Tôi có một nonpromic, giữ lại @property gọi là "xã hội" trong một bộ điều khiển xem và những báo cáo đăng nhập cùng một điều: NSLog (@ "% @", xã hội); và NSLog (@ "% @", self.social); Bạn có thể giải thích, Tom? – typeoneerror

+1

Đó là vì cả hai câu lệnh 'NSLog' đều in cùng một đối tượng. Sự khác biệt là 'self.social' gọi một phương thức trả về đối tượng và' social' chỉ là đối tượng. –

8

Những người khác đã trả lời 1-6 đầy đủ.

(7) Apple khuyên bạn nên sử dụng biến cá thể trực tiếp trong cả init và dealloc của bạn. Chủ yếu là vì đối tượng (đặc biệt nếu nó được phân lớp) chỉ được thiết lập một phần trong cả hai phương pháp này, và do đó việc gọi các bộ định tuyến/getters có thể dẫn đến hành vi không chính xác nếu chúng có bất kỳ điều gì khác ngoài hành động tầm thường. Nói chung, bạn có thể truy cập trực tiếp vào ivar một cách an toàn (thay vì thông qua getter) trong đối tượng của bạn, và nó sẽ hiệu quả hơn để làm như vậy (chỉ có liên quan trên iPhone). Nói chung, bạn nên sử dụng setter trong mọi trường hợp, đặc biệt nếu đối tượng của bạn có thể được phân lớp hoặc nếu người khác có thể quan sát thuộc tính.

(8) Bạn chưa bao giờ, gọi cho dealloc (ngoại trừ [super dealloc] từ bên trong phương thức dealloc). Nếu bạn có quyền sở hữu đối tượng khác, thì bạn nên từ bỏ quyền sở hữu đó (bằng cách gọi phát hành hoặc tự động phát hành). Hệ thống sau đó sẽ gọi dealloc trên đối tượng nếu thích hợp. Nhưng bạn không bao giờ gọi dealloc mình. Đọc số memory management rules (chỉ có 9 đoạn văn và rất quan trọng để hiểu).

+0

cảm ơn. tôi tìm thấy liên kết đến các quy tắc MM ở đâu đó mà ai đó đã chỉ ra. bệnh là đọc nó chắc chắn. –

+0

Btw, tất cả những câu hỏi này đến khi ý tưởng phát hành và nil của tôi bị tan vỡ sau một vụ tai nạn bất ngờ (ứng dụng bị treo sau khi tôi đặt tham chiếu đến nil). Tại sao trên trái đất sẽ chỉ định một con trỏ đến nil sụp đổ các ứng dụng? Kể từ đó, tôi đã sử dụng 'tự' ở mọi nơi mà tôi gán một con trỏ cho một tham chiếu khác. –

+0

Lý do duy nhất thiết lập một tham chiếu đến nil sẽ sụp đổ sẽ là nếu tham chiếu là một phần của một đối tượng không hợp lệ hoặc dealloced. Bật NSZombies và có lẽ điều đó sẽ hữu ích. –

0

Ok. Tôi đã xác nhận rằng không thiết lập B để nil đã làm các trick. Vì vậy, bây giờ, tôi không kiểm tra cho nil khi tạo bộ điều khiển B (khi tôi muốn điều hướng đến nó).

Thay vào đó, tôi phát hành B, sau đó tôi tạo ra bộ điều khiển và gán nó vào B. Sau đó, trong phương pháp viewDidAppear A, tôi phát hành B.

Tôi tin rằng chủ đề này hiện đang đóng cửa. Cảm ơn!

0

A4) Chúng khác nhau về loại của chúng. Tất cả chúng đều bằng không, nhưng NULL là một void *, nil là một id, và Nil là một con trỏ Class.

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