Các thuộc tính setter thuộc tính yếu và mạnh trong Objective-C


94

Sự khác biệt giữa các thuộc tính thiết lập thuộc tính yếu và mạnh trong Objective-C là gì?

@property(retain, [weak/strong]) __attribute__((NSObject)) CFDictionaryRef myDictionary;

Tác động và lợi ích là gì?

Tôi nghe nói rằng yếu không khả dụng trên iOS 4 và chúng tôi cần sử dụng gán.

Yếu tương tự để gán?


Câu trả lời:


102

Bạn có thể bật hoặc tắt ARC cho một tệp cụ thể. Nếu nó trên bạn không thể sử dụng retain release autoreleasevv ... Thay vào đó bạn sử dụng strong weakcho các thuộc tính hoặc __strong __weak cho các biến (mặc định là __strong). Strong tương đương với việc giữ lại, tuy nhiên ARC sẽ quản lý việc phát hành cho bạn.

Lần duy nhất bạn muốn sử dụng yếu, là nếu bạn muốn tránh các chu kỳ giữ lại (ví dụ: cha mẹ giữ lại con và con giữ lại cha mẹ nên cả hai đều không được giải phóng).

Phần 'bắc cầu miễn phí' (truyền từ NSđến CF) hơi phức tạp. Bạn vẫn phải quản lý thủ công CFRelease()CFRetain()cho các đối tượng CF. Khi bạn chuyển đổi chúng trở lại các đối tượng NS, bạn phải cho trình biên dịch biết về số lượng lưu giữ để nó biết bạn đã làm gì.

Tất cả ở đây .


119

Đây là thông tin tôi biết về thuộc tính biến

  1. nguyên tử // mặc định
  2. giải phẫu học
  3. strong = giữ lại // mặc định
  4. Yếu
  5. giữ lại
  6. gán // mặc định
  7. không an toàn
  8. sao chép
  9. chỉ đọc
  10. readwrite // default

vì vậy dưới đây là liên kết bài viết chi tiết nơi bạn có thể tìm thấy tất cả các thuộc tính đã đề cập ở trên, điều đó sẽ giúp bạn một cách bất chấp. Rất cảm ơn tất cả những người đã đưa ra câu trả lời tốt nhất ở đây !!

Thuộc tính biến hoặc Công cụ sửa đổi trong iOS

01. mạnh mẽ (iOS4 = giữ lại) keep - nó nói "giữ cái này trong đống cho đến khi tôi không chỉ vào nó nữa" - nói cách khác "Tôi là chủ sở hữu, bạn không thể giải quyết cái này trước khi nhắm mục tiêu tốt với cái đó giống như giữ lại “- Bạn chỉ sử dụng mạnh nếu cần giữ lại đối tượng. - Theo mặc định, tất cả các biến thể hiện và biến cục bộ là con trỏ mạnh. - Chúng tôi thường sử dụng strong cho UIViewControllers (cha mẹ của vật phẩm giao diện người dùng) - strong được sử dụng với ARC và về cơ bản nó sẽ giúp bạn, bằng cách không phải lo lắng về số lượng lưu giữ của một đối tượng. ARC tự động phát hành nó cho bạn khi bạn hoàn thành việc sử dụng nó. Sử dụng từ khóa mạnh có nghĩa là bạn sở hữu đối tượng.

Thí dụ:

@property (strong, nonatomic) ViewController *viewController;

@synthesize viewController;

02. yếu (iOS4 = secure_unretained) - nó nói "giữ cái này chừng nào người khác chỉ vào nó mạnh" - điều tương tự như gán, không giữ lại hoặc phát hành - Một tham chiếu "yếu" là một tham chiếu mà bạn không giữ lại. - Chúng tôi thường sử dụng yếu cho IBOutlets (UIViewController's Childs). Điều này hoạt động vì đối tượng con chỉ cần tồn tại miễn là đối tượng mẹ còn tồn tại. - một tham chiếu yếu là một tham chiếu không bảo vệ đối tượng được tham chiếu khỏi bộ thu gom rác. - Yếu về bản chất là gán, một tài sản không cố định. Ngoại trừ khi đối tượng được định vị, con trỏ yếu được tự động đặt thành nil

Thí dụ :

@property (weak, nonatomic) IBOutlet UIButton *myButton;

@synthesize myButton;

Giải thích : Cảm ơn BJ Homer

Hãy tưởng tượng đối tượng của chúng ta là một con chó, và con chó đó muốn chạy trốn (được định vị). Kẻ mạnh giống như một sợi dây buộc trên con chó. Chỉ cần bạn buộc dây xích vào người, chó sẽ không bỏ chạy. Nếu năm người gắn dây xích của họ vào một con chó, (năm con trỏ mạnh vào một đối tượng), thì con chó sẽ không bỏ chạy cho đến khi tất cả năm dây xích được tháo ra. Mặt khác, những người chỉ điểm yếu giống như những đứa trẻ chỉ vào con chó và nói "Nhìn kìa! Một con chó!" Miễn là con chó vẫn còn trên dây xích, những đứa trẻ nhỏ vẫn có thể nhìn thấy con chó và chúng sẽ vẫn chỉ vào nó. Tuy nhiên, ngay sau khi tất cả các dây xích được tháo ra, con chó sẽ chạy đi cho dù có bao nhiêu đứa trẻ đang chỉ vào nó. Ngay sau khi con trỏ mạnh cuối cùng (dây xích) không còn trỏ đến một đối tượng, đối tượng sẽ được phân bổ và tất cả các con trỏ yếu sẽ bị xóa. Khi chúng ta sử dụng yếu? Lần duy nhất bạn muốn sử dụng yếu, là nếu bạn muốn tránh các chu kỳ giữ lại (ví dụ: cha mẹ giữ lại con và con giữ lại cha mẹ nên cả hai đều không được giải phóng).


1
Trong danh sách ban đầu, tôi không thực sự chắc chắn ý bạn là "mặc định". Bạn có cả hai strong=retainassignđược gắn nhãn là mặc định, nhưng nó không thể là cả hai.
Slipp D. Thompson

27
Rất thích con chó trên so sánh dây xích. Giải thích nó khá tốt.
Jarrett Barnett

1
Giải thích tốt, mặc dù iOS không sử dụng tính năng thu gom rác. ARC! = Thu gom rác (!), Đây là những công nghệ khác nhau.

1
yếu và unsafe_unretained là khác nhau (những ứng dụng đầu tiên zero'ing tài liệu tham khảo yếu, trong khi sau này không ngồi xổm)
wcochran

1
Tôi chỉ đang học iOS, nhưng có vẻ như bạn đã đặt sai vị trí weakstrongtrong ví dụ của mình. Sẽ không có ý nghĩa hơn nếu cha mẹ có strongtham chiếu đến các con của nó (như thuộc myButtontính của UIViewControllerlớp mà bạn đã hiển thị weak) và con giữ các weaktham chiếu đến cha mẹ của chúng (như thuộc viewControllertính của một lớp con mà bạn ' thay vào đó đặt thành strong). Ví dụ, đọc Matt Neuburg của iOS 7 Programming Fundamentalsanh ta thấy rằng một lớp tuyên bố đại biểu của nó là một thuộc tính sẽ giữ cho nó `` yếu, điều đó có vẻ công bằng.
Bogdan Alexandru

2

Để gọi ra các phần của tài liệu được Robert tham chiếu trả lời hai câu hỏi cuối cùng của bạn một cách rõ ràng:

// The following declaration is similar to "@property(assign) MyClass *myObject;"
// except that if the MyClass instance is deallocated,
// the property value is set to nil instead of remaining as a dangling pointer.
@property(weak) MyClass *myObject;

Đây được coi là tham chiếu yếu về 0. Bạn có thể tạo các tham chiếu yếu không phải là zeroing các tham chiếu yếu bằng cách sử dụng __unsafe_unretained, nhưng như tên của nó, điều này thường không được khuyến khích.

Cũng trong tài liệu:

Weak references are not supported in Mac OS X v10.6 and iOS 4.

1
Vâng, điều này là chính xác, __unsafe_unretainedlà phiên bản ARC của assign.
Robert

2

Việc sử dụng thuộc tính WEAK rõ ràng như sau:

Any control whose properties we need to change(eg:text of a label) is declared weak and as below:

@property(nonatomic,weak) IBOutlet Type *name;
Eg: @property(nonatomic,weak) IBOutlet UILabel *myLabel;

1
Sử dụng yếu trên thuộc tính của mình, tôi nhận được cảnh báo: "Bộ thu yếu có thể không thể đoán trước được đặt thành nil". Tôi đã thấy một số bài đăng khác mà để ngăn cảnh báo này, bạn phải tạo một tham chiếu mạnh cục bộ. Và nếu điều này là đúng, thì đâu là điểm khiến một thuộc tính yếu đi, nếu cuối cùng tôi phải tạo một tham chiếu mạnh?
arh

0

hãy lấy một ví dụ để giải thích thêm (câu trả lời ở trên đã rất tuyệt rồi), ví dụ này có thể giúp ích được nhiều hơn không

hãy để chúng tôi có hai lớp A và B

//A.h

#import <Foundation/Foundation.h>
#import "B.h"

@interface A : NSObject

@property (nonatomic, strong) B *objB;

@end

@implementation A
//

@end

//B.h

    #import <Foundation/Foundation.h>
    #import "A.h"


    @interface B : NSObject

    @property strong text(nonatomic, strong) A *objA;

    @end

    @implementation B
    //

    @end

    and in main

    #import "B.h"
    #import "A.h"

    {
    A *obja =[[A alloc]init];
    B *objb =[[B alloc]init];
    A.objB=objb;
    B.objA=obja;
   }

đoạn mã trên sẽ tạo ra một chu kỳ lưu giữ vì cả hai đều là loại mạnh a --------> b ---------> a

vì vậy để tránh nó, bạn phải sử dụng thuộc tính tuần của một trong số đó để hàng tuần nó tham chiếu đến đối tượng và không tăng số lượng tham chiếu của nó.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.