2011-08-15 33 views
13

là những gì khác biệt có thể thay đổi và bất biếnlà những gì khác biệt giữa có thể thay đổi và bất biến

như

NSString và NSMutableString.

NSArray và NSMutableArray.

NSDictionary và NSMutableDictionary.

khác biệt giữa đối tượng có thể thay đổi và các đối tượng khác [mà tôi đoán bất biến]

@thanks trước là gì.

+1

Câu hỏi tiếp theo tốt sẽ là * tại sao * NSArray, NSString, NSSet, NSDictionary, v.v. * là * không thay đổi. –

Trả lời

16

Một đối tượng có thể thay đổi có thể được biến đổi hoặc đã thay đổi. Một vật bất biến không thể. Ví dụ, trong khi bạn có thể thêm hoặc loại bỏ các đối tượng từ một NSMutableArray, bạn không thể làm một trong hai với một NSArray.

Các đối tượng có thể thay đổi có thể có các thành phần thay đổi, thêm vào hoặc xóa, không thể đạt được với các đối tượng bất biến. Các đối tượng không thay đổi được mắc kẹt với bất kỳ đầu vào nào bạn đã cho chúng trong bộ khởi tạo [[object alloc] initWith...] của chúng.

Ưu điểm của các đối tượng có thể thay đổi của bạn là hiển nhiên, nhưng chúng chỉ nên được sử dụng khi cần thiết (thường ít hơn bạn nghĩ) khi chúng chiếm nhiều bộ nhớ hơn đối tượng không thay đổi.

+1

Bạn có thể chấp nhận câu trả lời mà không cần điểm danh tiếng. Xem: http://meta.stackexchange.com/questions/91889/how-do-i-accept-an-answer-to-my-questions –

+0

FWIW, tôi không chắc chắn rằng các đối tượng có thể thay đổi được sử dụng nhiều bộ nhớ hơn cho mỗi lần. Tôi cũng nghĩ rằng đó không phải là lý do chính họ tồn tại. Chúng tồn tại vì các đối tượng bất biến có thể dễ dàng sử dụng hơn trong môi trường đa luồng, AFAIK. –

+0

Nếu bạn đã sử dụng NSMutableString trong ứng dụng của mình ở mọi nơi bạn đã sử dụng NSString - Tôi nghĩ bạn sẽ thấy một lần truy cập hiệu suất đáng kể. –

5

Một đối tượng có thể thay đổi có thể bị đột biến hoặc thay đổi. Một vật bất biến không thể. Ví dụ, trong khi bạn có thể thêm hoặc loại bỏ các đối tượng từ một NSMutableArray, bạn không thể làm một trong hai với một NSArray.

+0

cảm ơn Glorified Hacker. Tôi xem phim X-Man để những người đột biến có thể thay đổi hành vi đó khi họ cần. Ở đây làm thế nào các đối tượng thay đổi hành vi của nó, bạn có thể cho tôi một ví dụ cho rằng ......... xin lỗi về ví dụ phim của tôi. – user891268

+0

Mutable không có nghĩa là hành vi của đối tượng có thể được thay đổi, điều đó có nghĩa là dữ liệu có thể được thay đổi. Bạn có thể thêm "World" vào một đối tượng NSMutableString có chứa "Hello", nhưng không phải đối tượng NSString chứa "Hello". – glorifiedHacker

+0

nhờ dữ liệu của nó mà trong đối tượng được thay đổi trong mutable không phải trong bất biến [Unchangeable] cảm ơn rất nhiều người bạn. – user891268

2

Định nghĩa tiếng Anh là "mutable" thực sự là tất cả những gì bạn cần ở đây. Các đối tượng có thể thay đổi có thể được sửa đổi sau khi tạo. Không thể sửa đổi các đối tượng không thể thay đổi sau khi tạo. Điều đó áp dụng cho tất cả các lớp bạn đã liệt kê.

Thực tế mà nói, tất cả các lớp học có thể thay đổi là lớp con của những người không thay đổi, và mỗi thêm giao diện riêng của mình để cho phép sửa đổi chương trình của đối tượng, như addObject:, setObject:forKey:, vv ...

8

đối tượng Mutable có thể các đối tượng sửa đổi, không thay đổi không thể.

Ví dụ: NSMutableArray có addObject:removeObject: phương pháp (và nhiều hơn nữa), nhưng NSArray thì không.

chuỗi Sửa đổi:

NSString *myString = @"hello"; 
myString = [myString stringByAppendingString:@" world"]; 

vs

đối tượng Mutable đặc biệt hữu ích khi giao dịch với mảng,

Ví dụ nếu bạn có một NSArray của NSMutableStrings bạn có thể làm:

[myArray makeObjectsPerformSelector:@selector(appendString:) withObject:@"!!!"]; 

sẽ thêm 3! đến cuối mỗi chuỗi trong mảng.

Nhưng nếu bạn có một NSArray của NSStrings (do đó không thay đổi), bạn không thể làm được điều này (ít nhất là nó rất nhiều khó khăn hơn, và mã hơn, vì sử dụng NSMutableString)

1

Có thể thay đổi đột biến, không thay đổi được. Khi bạn chia sẻ một đối tượng có thể thay đổi, bạn nên mong đợi một số đối tượng có thể thay đổi nó. Khi bạn chia sẻ một đối tượng không thay đổi, bạn dự kiến ​​sẽ không có ai thay đổi.

1

Có một số khác biệt khác thú vị là một đối tượng bất biến khi sao chép thay vào đó sẽ được giữ lại. Cũng có thể có rất nhiều sự khác biệt mà Apple thực hiện vì lý do hiệu suất phụ thuộc vào việc một đối tượng có thể thay đổi hay không, ví dụ, làm các phương thức chuỗi con sao chép các byte thực của chuỗi cha hoặc làm một điểm phụ chuỗi gốc nếu nó không thay đổi, có thể xảy ra nhưng không biết ai.

5

Sự khác biệt cơ bản là:

  • NSStrings không thể chỉnh sửa, chỉ bố trí. Điều này có nghĩa là khi giá trị của một thay đổi NSString, nó thực sự trỏ đến một vị trí mới trong bộ nhớ.

  • Các đối tượng NSMutableString có thể được chỉnh sửa và duy trì cùng một con trỏ.

Một sự khác biệt thực tế phổ biến là:

  • Nếu bạn tạo 1 NSString và sau đó gán nhau với nó, sau đó chỉnh sửa hoặc một trong số họ, họ bây giờ sẽ được trỏ đến dây khác nhau .

  • Nếu bạn làm điều tương tự với NSMutableStrings, nhưng sau đó chỉ cần chỉnh sửa một trong số chúng (không gán lại), cả hai đều sẽ trỏ đến đối tượng mới được chỉnh sửa.

2

Mọi người đều nói bạn không thể thay đổi/sửa đổi đối tượng bất biến. Tôi có một cách giải thích khác. Bạn có thể sửa đổi nó, nhưng sau đó bạn sẽ tạo một con trỏ mới mới đến đối tượng mới, nó không giống như bạn đã sửa đổi đối tượng cũ, một thương hiệu của nó. Mới. Vật. Bất kỳ con trỏ nào có con trỏ trỏ trước đó, sẽ không thấy thay đổi của nó. Tuy nhiên nếu nó là một đối tượng Mutable, bất kỳ đối tượng trỏ trước đó nào đối tượng sẽ thấy giá trị mới của nó. Xem các ví dụ. FYI %p in vị trí con trỏ trong heap.

NSString * A = @"Bob"; 
    NSString * B = @"Bob"; 
    NSString * C = @"Bob1"; 
    NSString * D = A; 
    NSLog(@"\n %p for A \n %p for B \n %p for C \n %p for D",A,B,C,D); 

    // memory location of A,B,D are same. 

0x104129068 cho A
0x104129068 cho B
0x104129088 cho C
0x104129068 cho D


Sửa đổi đối tượng con trỏ của một

A = @"Bob2"; // this would create a new memory location for A, its previous memory location is still retained by B 
NSLog(@"\n%p for A \n%p for B \n%p for C \n %p for D",A,B,C, D); 

// A has a **new** memory location, B,D have same memory location. 

0x1041290c8 cho A
0x104129068 cho B
0x104129088 cho C
0x104129068 cho D


// NSMutableString * AA = @"Bob"; <-- you CAN'T do this you will get error: Incompatible pointer types initializing NSMutableString with an Expression of type NSString 
    NSMutableString * AA = [NSMutableString stringWithString:@"Bob1"]; 
    NSString * BB = @"Bob"; 
    NSString * CC = @"Bob1"; 
    NSString * DD = AA; 
    NSLog(@"\n %p for AA \n %p for BB \n %p for CC \n %p for DD",AA,BB,CC,DD); 

    // memory location of AA,DD are same. 

0x7ff26af14490 cho AA
0x104129068 cho BB
0x104129088 cho CC
0x7ff26af14490 cho DD


Sửa đổi con trỏ AA của đối tượng

AA = (NSMutableString*)@"Bob3"; // This would NOT create a new memory location for A since its Mutable-- D was and still pointing to some location 
    NSLog(@"\n%p for AA \n%p for BB \n%p for CC \n %p for D",AA,BB,CC,DD); 

    // memory location of AA,DD are NOT same. 

0x104129128 cho AA
0x104129068 cho BB
0x104129088 cho CC
0x7ff26af14490 cho DD

Như bạn có thể tưởng tượng, thuộc tính lưu trữ mặc định cho tất cả thuộc tính NSString là retain. Để biết thêm thông tin về copy & retain Tôi khuyên bạn nên đọc câu hỏi này. NSString property: copy or retain?

+0

Xin lỗi, nhưng đây là một hỗn hợp khó hiểu và không chính xác. Bạn không thể sửa đổi các đối tượng bất biến, bạn có thể sửa đổi giá trị được lưu trữ trong một biến kiểu tham chiếu - do đó thay đổi đối tượng nào được tham chiếu, bạn nên ** không bao giờ ** bỏ một hằng chuỗi thành 'NSMutableString *' - nó không tạo ra một chuỗi có thể thay đổi, gán cho một biến không tạo ra bất kỳ thứ gì "mới" như câu trả lời dường như đề xuất, v.v. – CRD

+0

@CRD bạn có thể đề xuất chỉnh sửa không? – Honey

+0

Xin lỗi, không. Nó sẽ yêu cầu khá viết lại, và có câu trả lời khác ở đây. – CRD

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