Ký hiệu dấu chấm so với ký hiệu thông báo cho các thuộc tính đã khai báo


81

Bây giờ chúng ta có ký hiệu "dấu chấm" cho các thuộc tính. Tôi đã nhìn thấy nhiều trở lạiforths về giá trị của ký hiệu dấu chấm vs kí hiệu tin nhắn. Để giữ cho các câu trả lời không bị xáo trộn, tôi sẽ không trả lời theo cách nào trong câu hỏi.

Suy nghĩ của bạn về ký hiệu dấu chấm so với ký hiệu thông báo để truy cập thuộc tính?

Hãy cố gắng giữ nó tập trung vào Objective-C - một thành kiến ​​của tôi mà tôi sẽ đưa ra là Objective-C là Objective-C, vì vậy tùy chọn của bạn rằng nó giống như Java hoặc JavaScript là không hợp lệ.

Bình luận hợp lệ liên quan đến các vấn đề kỹ thuật (thứ tự hoạt động, ưu tiên sử dụng, hiệu suất, v.v.), tính rõ ràng (cấu trúc so với bản chất đối tượng, cả chuyên nghiệp và con!), Tính ngắn gọn, v.v.

Lưu ý, tôi thuộc trường phái về chất lượng nghiêm ngặt và khả năng đọc mã đã làm việc trong các dự án lớn nơi quy ước và chất lượng mã là điều tối quan trọng (mô hình viết một lần đọc một nghìn lần).


14
+1 đây là một câu hỏi hay và bạn sẽ nhận được rất nhiều câu trả lời mâu thuẫn. =)
Dave DeLong

1
Trình chỉnh sửa mã nguồn nên điều chỉnh theo sở thích cá nhân của lập trình viên, mà không thay đổi các ký tự của chính tệp. Bằng cách đó, mọi người sẽ có được những gì họ thích.
Arne Evertsson

Câu trả lời:


64

Không sử dụng dấu chấm cho hành vi. Sử dụng dấu chấm để truy cập hoặc đặt thuộc tính như nội dung, thường là các thuộc tính được khai báo là thuộc tính.

x = foo.name; // good
foo.age = 42; // good

y = x.retain; // bad

k.release; // compiler should warn, but some don't. Oops.

v.lockFocusIfCanDraw; /// ooh... no. bad bad bad

Đối với những người mới làm quen với Objective-C, tôi khuyên bạn không nên sử dụng dấu chấm cho bất kỳ thứ gì ngoài những thứ được khai báo là @property. Một khi bạn có cảm giác với ngôn ngữ, hãy làm những gì bạn cảm thấy phù hợp.

Ví dụ, tôi thấy điều sau hoàn toàn tự nhiên:

k = anArray.count;
for (NSView *v in myView.subviews) { ... };

Bạn có thể mong đợi rằng trình phân tích tĩnh clang sẽ phát triển khả năng cho phép bạn kiểm tra xem dấu chấm đó chỉ được sử dụng cho một số mẫu nhất định hay không cho một số mẫu khác.


18
Chà, tôi thậm chí còn không biết bạn có thể sử dụng cú pháp dấu chấm cho bất kỳ thứ gì khác ngoài thuộc tính. Màu sắc tôi ngạc nhiên! (Nhưng tôi đồng ý, dấu chấm chỉ nên được sử dụng cho các thuộc tính)
jbrennan

13
Điều đó là không chính xác. Ký hiệu dấu chấm là một từ đồng nghĩa chuyển tiếp cho một lệnh gọi phương thức tương đương; không hơn không kém.
bbum

2
Tôi tự hỏi tại sao ký hiệu dấu chấm không bị hạn chế đối với những người truy cập được khai báo thuộc tính @. Có vẻ như nó sẽ cho phép các tác giả của lớp giải quyết các vùng xám trên đó các phương thức nên được cho phép trong ký hiệu dấu chấm và sẽ không cảm thấy quá mơ hồ liệu có nên sử dụng các phương thức như .uppercaseStringnếu lớp được phép thể hiện ý định của mình và có nó được thực thi bởi trình biên dịch. Có lẽ có điều gì đó tôi đang thiếu yêu cầu triển khai hiện tại của ký hiệu dấu chấm.

4
Nó có thể chỉ được giới hạn ở mức độ @propertynhưng điều đó sẽ yêu cầu người tiêu dùng API phải tìm hiểu một thứ nguyên thông tin boolean khác và các nhà thiết kế API rất có thể bị chìm trong các tranh luận về điều gì nên và không nên @property. Lưu ý rằng Xcode thích - coi trọng @propertycác phương pháp ngụ ý hơn khi hoàn thành mã .... Nó được khuyến khích, nhưng không được thực thi.
bbum

1
@rodamn Nó trả lời rằng; nó khuyến nghị chỉ sử dụng dấu chấm với những người truy cập đã @propertykhai báo khi mới sử dụng ngôn ngữ. Khi một người có được sự tự tin với việc viết mã trong Objective-C, hãy làm những gì cảm thấy đúng. Hấp dẫn; nhiều người trong chúng ta đã quay trở lại việc sử dụng rất hạn chế dấu chấm.
bbum

22

Hãy để tôi bắt đầu bằng cách nói rằng tôi bắt đầu lập trình bằng Visual / Real Basic, sau đó chuyển sang Java, vì vậy tôi khá quen với việc chấm cú pháp. Tuy nhiên, cuối cùng khi tôi chuyển sang Objective-C và làm quen với dấu ngoặc, sau đó thấy phần giới thiệu Objective-C 2.0 và cú pháp dấu chấm của nó, tôi nhận ra rằng tôi thực sự không thích nó. (đối với các ngôn ngữ khác thì không sao, vì đó là cách chúng cuộn).

Tôi có ba loại thịt bò chính với cú pháp dấu chấm trong Objective-C:

Thịt bò # 1: Không rõ tại sao bạn có thể mắc lỗi. Ví dụ, nếu tôi có dòng:

something.frame.origin.x = 42;

Sau đó, tôi sẽ gặp lỗi trình biên dịch, vì somethinglà một đối tượng và bạn không thể sử dụng cấu trúc của một đối tượng làm giá trị của một biểu thức. Tuy nhiên, nếu tôi có:

something.frame.origin.x = 42;

Sau đó, điều này biên dịch tốt, bởi vì somethingbản thân một cấu trúc có một thành viên NSRect, và tôi có thể sử dụng nó như một giá trị.

Nếu tôi đang sử dụng mã này, tôi sẽ cần dành một chút thời gian để cố gắng tìm ra nó somethinglà gì . Nó có phải là một cấu trúc không? Nó là một đối tượng? Tuy nhiên, khi chúng ta sử dụng cú pháp ngoặc, nó rõ ràng hơn nhiều:

[something setFrame:newFrame];

Trong trường hợp này, hoàn toàn không có sự mơ hồ nếu somethinglà một đối tượng hay không. Giới thiệu mập mờ là thịt bò # 1 của tôi.

Beef # 2: Trong C, cú pháp dấu chấm được sử dụng để truy cập các thành viên của cấu trúc, không phải phương thức gọi. Người lập trình có thể ghi đè các phương thức setFoo:foođối tượng, nhưng vẫn truy cập chúng qua something.foo. Trong tâm trí của tôi, khi tôi nhìn thấy các biểu thức sử dụng cú pháp dấu chấm, tôi mong đợi chúng là một phép gán đơn giản thành một ivar. Đây không phải là luôn luôn như vậy. Hãy xem xét một đối tượng bộ điều khiển trung gian một mảng và một chế độ xem bảng. Nếu tôi gọi myController.contentArray = newArray;, tôi sẽ mong đợi nó sẽ thay thế mảng cũ bằng mảng mới. Tuy nhiên, lập trình viên ban đầu có thể đã ghi đè setContentArray:để không chỉ đặt mảng mà còn tải lại chế độ xem bảng. Từ dòng, không có dấu hiệu của hành vi đó. Nếu tôi muốn nhìn thấy[myController setContentArray:newArray];, sau đó tôi sẽ nghĩ "Aha, một phương pháp. Tôi cần đi xem định nghĩa của phương pháp này chỉ để đảm bảo rằng tôi biết nó đang làm gì."

Vì vậy, tôi nghĩ rằng bản tóm tắt của tôi về Beef # 2 là bạn có thể ghi đè ý nghĩa của cú pháp dấu chấm bằng mã tùy chỉnh.

Thịt bò # 3: Tôi nghĩ nó có vẻ tệ. Là một lập trình viên Objective-C, tôi hoàn toàn quen với cú pháp ngoặc, vì vậy việc đọc dọc và nhìn thấy các dòng và dòng trong dấu ngoặc đẹp và sau đó đột ngột bị ngắt với foo.name = newName; foo.size = newSize;vv là một chút phân tâm đối với tôi. Tôi nhận ra rằng một số thứ yêu cầu cú pháp dấu chấm (cấu trúc C), nhưng đó là lần duy nhất tôi sử dụng chúng.

Tất nhiên, nếu bạn đang viết mã cho chính mình, thì hãy sử dụng bất cứ thứ gì bạn cảm thấy thoải mái. Nhưng nếu bạn đang viết mã mà bạn đang có kế hoạch tìm nguồn mở hoặc bạn đang viết thứ gì đó mà bạn không mong đợi sẽ duy trì mãi mãi, thì tôi thực sự khuyến khích sử dụng cú pháp ngoặc. Tất nhiên, đây chỉ là ý kiến ​​của tôi.

Bài đăng trên blog gần đây chống lại cú pháp dấu chấm: http://weblog.bignerdranch.com/?p=83

Bác bỏ bài đăng trên: http://eschatologist.net/blog/?p=226 (với bài viết gốc ủng hộ cú pháp chấm: http://eschatologist.net/blog/?p=160 )


5
Thịt bò # 1 có vẻ hơi khó hiểu đối với tôi. Tôi không hiểu đó là mối quan tâm như thế nào ngoài việc bạn có thể thử gửi một tin nhắn đến một cấu trúc và sau đó phải tìm ra rằng biến thực sự là một cấu trúc. Bạn có thực sự thấy rất nhiều người hiểu cách hoạt động của nó đang bối rối trước điều này trong thực tế không? Điều này có vẻ giống như kiểu mà bạn sẽ làm rối một lần, tìm hiểu về thứ giá trị, và sau đó thực hiện nó ngay trong tương lai - giống như, chẳng hạn, không cố gắng đối xử với NSNumbers như int.
Chuck

2
@Chuck nó là một trường hợp phức tạp, nhưng tôi thực hiện khá nhiều việc phát triển hợp đồng, liên quan đến việc kế thừa các dự án và phải làm việc với chúng. Thông thường something là một đối tượng, nhưng tôi đã gặp một vài nơi mà các tác giả ban đầu đã tạo cấu trúc (để tăng tốc độ, sử dụng bộ nhớ thấp hơn, v.v.) và tôi phải dành vài phút để cố gắng tìm ra lý do tại sao mã không ' t biên dịch.
Dave DeLong 14/08/09

14

Tôi là một nhà phát triển Cocoa / Objective-C mới và công việc của tôi là:

Tôi gắn bó với ký hiệu nhắn tin, mặc dù tôi đã bắt đầu với Obj-C 2.0 và mặc dù ký hiệu dấu chấm có cảm giác quen thuộc hơn (Java là ngôn ngữ đầu tiên của tôi.) Lý do của tôi khá đơn giản: Tôi vẫn không hiểu chính xác tại sao họ thêm ký hiệu dấu chấm vào ngôn ngữ. Đối với tôi nó có vẻ như là một sự bổ sung không cần thiết, "không tinh khiết". Mặc dù nếu ai đó có thể giải thích nó mang lại lợi ích như thế nào cho ngôn ngữ, tôi rất vui khi được nghe.

Tuy nhiên, tôi coi đây là một lựa chọn theo phong cách và tôi không nghĩ có cách nào đúng hay sai, miễn là nó nhất quán và dễ đọc , giống như với bất kỳ lựa chọn phong cách nào khác (chẳng hạn như đặt dấu ngoặc nhọn mở đầu của bạn trên cùng một dòng như tiêu đề phương thức hoặc dòng tiếp theo).


2
+1 câu trả lời tuyệt vời. Tôi thực sự muốn biết "tại sao" đằng sau nó. Có lẽ bbum hoặc mmalc biết câu trả lời ... (cả hai đều làm việc tại )
Dave DeLong

11

Ký hiệu dấu chấm Objective-C là một đường cú pháp được dịch sang cách truyền thông báo bình thường, do đó, không có gì thay đổi và không có gì khác biệt trong thời gian chạy. Ký hiệu dấu chấm nó hoàn toàn không nhanh hơn việc truyền thông điệp.

Sau phần mở đầu nhỏ cần thiết này, đây là ưu và nhược điểm của tôi:

Ưu và nhược điểm của ký hiệu dấu chấm

  • thuận

    • dễ đọc: ký hiệu dấu chấm dễ đọc hơn các dấu ngoặc lồng nhau xoa bóp
    • Nó đơn giản hóa sự tương tác với Thuộc tính và Thuộc tính: sử dụng ký hiệu dấu chấm cho các thuộc tính và ký hiệu thông báo cho các phương thức, bạn có thể đạt được sự phân tách trạng thái và hành vi ở cấp cú pháp
    • Có thể sử dụng toán tử gán ghép (1) .
    • bằng cách sử dụng @propertyký hiệu và dấu chấm, trình biên dịch sẽ làm rất nhiều việc cho bạn, nó có thể tạo mã để Quản lý Bộ nhớ tốt khi nhận và thiết lập thuộc tính; đây là lý do tại sao ký hiệu dấu chấm được đề xuất bởi chính các hướng dẫn chính thức của Apple.
  • khuyết điểm

    • Ký hiệu dấu chấm chỉ được phép truy cập vào một @property
    • Vì Objective-C là một lớp trên tiêu chuẩn C (phần mở rộng ngôn ngữ), ký hiệu dấu chấm không thực sự làm rõ thực thể được truy cập là một đối tượng hay một cấu trúc. Thông thường, có vẻ như bạn đang truy cập các thuộc tính của một cấu trúc.
    • gọi một phương thức với ký hiệu dấu chấm, bạn sẽ mất lợi thế về khả năng đọc các tham số được đặt tên
    • khi ký hiệu thư hỗn hợp và ký hiệu dấu chấm có vẻ như bạn đang viết mã bằng hai ngôn ngữ khác nhau

Ví dụ về mã:

(1) Ví dụ về mã sử dụng toán tử kết hợp:

//Use of compound operator on a property of an object
anObject.var += 1;
//This is not possible with standard message notation
[anObject setVar:[anObject var] + 1];

7

Sử dụng phong cách của một ngôn ngữ, nhất quán với chính ngôn ngữ đó, là lời khuyên tốt nhất ở đây. Tuy nhiên, đây không phải là trường hợp viết mã chức năng trong hệ thống OO (hoặc ngược lại) và ký hiệu dấu chấm là một phần của cú pháp trong Objective-C 2.0.

Bất kỳ hệ thống nào cũng có thể bị sử dụng sai. Sự tồn tại của bộ tiền xử lý trong tất cả các ngôn ngữ dựa trên C là đủ để làm những điều thực sự khá kỳ lạ; chỉ cần nhìn vào Cuộc thi Obfuscated C nếu bạn cần biết chính xác nó có thể trở nên kỳ lạ như thế nào. Điều đó có nghĩa là bộ tiền xử lý tự động bị hỏng và bạn không bao giờ nên sử dụng nó?

Sử dụng cú pháp dấu chấm để truy cập các thuộc tính, đã được định nghĩa như vậy trong giao diện, là hành vi lạm dụng. Sự tồn tại của lạm dụng ở Potentia không nhất thiết phải là lý lẽ chống lại nó.

Quyền truy cập tài sản có thể có tác dụng phụ. Điều này là trực giao với cú pháp được sử dụng để có được thuộc tính đó. CoreData, ủy quyền, thuộc tính động (đầu tiên + cuối cùng = đầy đủ) tất cả sẽ nhất thiết phải thực hiện một số công việc dưới vỏ bọc. Nhưng điều đó sẽ gây nhầm lẫn giữa 'biến cá thể' với 'thuộc tính' của một đối tượng. Không có lý do gì tại sao các thuộc tính nhất thiết phải được lưu trữ nguyên trạng, đặc biệt nếu chúng có thể được tính toán (ví dụ: độ dài của một chuỗi chẳng hạn). Vì vậy, cho dù bạn sử dụng foo.fullName hay [foo fullName] thì vẫn sẽ có đánh giá động.

Cuối cùng, hành vi của thuộc tính (khi được sử dụng làm giá trị ) được xác định bởi chính đối tượng, chẳng hạn như việc một bản sao được lấy hay liệu nó được giữ lại. Điều này giúp bạn dễ dàng thay đổi hành vi sau này - trong chính định nghĩa thuộc tính - thay vì phải triển khai lại các phương thức. Điều đó làm tăng thêm tính linh hoạt của cách tiếp cận, với khả năng xảy ra (triển khai) ít lỗi hơn. Vẫn có khả năng chọn sai phương pháp (tức là sao chép thay vì giữ lại) nhưng đó là vấn đề kiến ​​trúc chứ không phải triển khai.

Cuối cùng, câu hỏi 'nó trông giống như một cấu trúc'. Đây có lẽ là điểm khác biệt chính trong các cuộc tranh luận cho đến nay; nếu bạn có một cấu trúc, nó hoạt động khác với khi bạn có một đối tượng. Nhưng điều đó luôn đúng; bạn không thể gửi một thông điệp có cấu trúc và bạn cần biết liệu nó dựa trên ngăn xếp hay dựa trên tham chiếu / malloc. Đã có các mô hình tinh thần khác nhau về cách sử dụng ([[CGRect cert] init] hoặc struct CGRect?). Họ chưa bao giờ thống nhất về hành vi; bạn cần biết những gì bạn đang giải quyết trong từng trường hợp. Thêm ký hiệu thuộc tính cho các đối tượng rất khó có thể gây nhầm lẫn cho bất kỳ lập trình viên nào biết kiểu dữ liệu của chúng là gì; và nếu không, họ gặp vấn đề lớn hơn.

Đối với tính nhất quán; (Mục tiêu-) C không nhất quán trong chính nó. = được sử dụng cho cả gán và bình đẳng, dựa trên vị trí từ vựng trong mã nguồn. * được sử dụng cho con trỏ và phép nhân. BOOL là ký tự, không phải byte (hoặc giá trị số nguyên khác), mặc dù CÓ và KHÔNG lần lượt là 1 và 0. Tính nhất quán hay tinh khiết không phải là những gì ngôn ngữ được thiết kế cho; đó là về việc hoàn thành công việc.

Vì vậy, nếu bạn không muốn sử dụng nó, đừng sử dụng nó. Làm theo một cách khác. Nếu bạn muốn sử dụng nó, và bạn hiểu nó, bạn dùng nó cũng được. Các ngôn ngữ khác giải quyết các khái niệm về cấu trúc dữ liệu chung (bản đồ / cấu trúc) và kiểu đối tượng (có thuộc tính), thường sử dụng cùng một cú pháp cho cả hai mặc dù thực tế rằng một bên chỉ là một cấu trúc dữ liệu và một bên là một đối tượng phong phú. Các lập trình viên trong Objective-C phải có khả năng tương đương để có thể đối phó với tất cả các kiểu lập trình, ngay cả khi nó không phải là kiểu bạn ưa thích.


6

Tôi sử dụng nó cho tài sản bởi vì

for ( Person *person in group.people){ ... }

dễ đọc hơn một chút

for ( Person *person in [group  people]){ ... }

trong trường hợp thứ hai, khả năng đọc được xen kẽ bằng cách đặt bộ não của bạn vào chế độ gửi tin nhắn, trong khi trong trường hợp đầu tiên, rõ ràng là bạn đang truy cập thuộc tính people của đối tượng nhóm.

Tôi cũng sẽ sử dụng nó khi sửa đổi một bộ sưu tập, ví dụ:

[group.people addObject:another_person];

dễ đọc hơn một chút

[[group people] addObject:another_person];

Điểm nhấn trong trường hợp này là hành động thêm một đối tượng vào mảng thay vì xâu chuỗi hai thông báo.


5

Tôi hầu hết đã được lớn lên trong thời đại Objective-C 2.0 và tôi thích ký hiệu dấu chấm hơn. Đối với tôi, nó cho phép đơn giản hóa mã, thay vì có thêm dấu ngoặc, tôi chỉ có thể sử dụng dấu chấm.

Tôi cũng thích cú pháp dấu chấm vì nó khiến tôi thực sự cảm thấy như đang truy cập một thuộc tính của đối tượng, thay vì chỉ gửi nó một tin nhắn (tất nhiên cú pháp dấu chấm thực sự chuyển thành gửi tin nhắn, nhưng vì mục đích xuất hiện , dấu chấm có cảm giác khác). Thay vì "gọi một getter" theo cú pháp cũ, nó thực sự cảm thấy như tôi đang trực tiếp nhận được thứ gì đó hữu ích từ đối tượng.

Một số cuộc tranh luận xung quanh vấn đề này liên quan đến "Nhưng chúng ta đã có cú pháp dấu chấm, và nó dành cho structs!". Và đó là sự thật. Nhưng (và một lần nữa, đây chỉ là tâm lý) về cơ bản tôi cảm thấy như vậy. Truy cập vào một tài sản của một đối tượng sử dụng dot-cú pháp cảm thấy giống như truy cập vào một thành viên của một cấu trúc, mà là nhiều hơn hoặc ít ảnh hưởng có ý định (theo ý kiến của tôi).

**** Chỉnh sửa: Như bbum đã chỉ ra, bạn cũng có thể sử dụng cú pháp dấu chấm để gọi bất kỳ phương thức nào trên một đối tượng (tôi không biết về điều này). Vì vậy, tôi sẽ nói ý kiến ​​của tôi về cú pháp dấu chấm chỉ để xử lý các thuộc tính của một đối tượng, không phải gửi tin nhắn hàng ngày **


3

Tôi thích cú pháp nhắn tin hơn ... nhưng chỉ vì đó là những gì tôi đã học được. Xem xét nhiều lớp của tôi và những gì không thuộc kiểu Objective-C 1.0, tôi sẽ không muốn trộn chúng. Tôi không có lý do thực sự nào ngoài "những gì tôi đã quen" để không sử dụng cú pháp dấu chấm ... NGOẠI TRỪ cho điều này, điều này khiến tôi INSANE

[myInstance.methodThatReturnsAnObject sendAMessageToIt]

Tôi không biết tại sao, nhưng nó thực sự làm tôi tức giận, không có lý do chính đáng. Tôi chỉ nghĩ rằng làm

[[myInstance methodThatReturnsAnObject] sendAMessageToIt]

dễ đọc hơn. Nhưng để mỗi riêng của mình!


3
Tôi thực hiện việc này theo thời gian, nhưng chỉ khi tôi đang truy cập một thuộc tính. Ví dụ: [self.title lowercaseString]hoặc cái gì đó. Nhưng tôi có thể hiểu theo phong cách tại sao việc trộn và kết hợp cú pháp lại khó chịu. Lý do duy nhất tôi làm là để giữ thẳng thuộc tính là gì và phương thức trả về một đối tượng là gì (tôi biết thuộc tính thực sự chỉ có vậy, nhưng bạn hy vọng hiểu được ý tôi).
jbrennan

3

Thành thật mà nói, tôi nghĩ nó phụ thuộc vào vấn đề phong cách. Cá nhân tôi phản đối cú pháp dấu chấm (đặc biệt là sau khi phát hiện ra rằng bạn có thể sử dụng nó cho các cuộc gọi phương thức chứ không chỉ đọc / ghi các biến). Tuy nhiên, nếu bạn định sử dụng nó, tôi thực sự khuyên bạn không nên sử dụng nó cho bất kỳ việc gì khác ngoài việc truy cập và thay đổi các biến.


3

Một trong những ưu điểm chính của lập trình hướng đối tượng là không có quyền truy cập trực tiếp vào trạng thái bên trong của các đối tượng.

Cú pháp dấu chấm đối với tôi dường như là một nỗ lực để làm cho nó trông và cảm thấy như thể trạng thái đang được truy cập trực tiếp. Nhưng trên thực tế, nó chỉ là đường cú pháp đối với các hành vi -foo và -setFoo :. Bản thân tôi, tôi thích gọi một cái thuổng hơn. Cú pháp dấu chấm giúp dễ đọc đến mức mã ngắn gọn hơn, nhưng nó không giúp dễ hiểu vì không nhớ rằng bạn thực sự đang gọi -foo và -setFoo: có thể gặp rắc rối về chính tả.

Đối với tôi, các trình truy cập tổng hợp dường như là một nỗ lực giúp dễ dàng ghi các đối tượng ở trạng thái được truy cập trực tiếp. Tôi tin rằng điều này khuyến khích chính xác kiểu thiết kế chương trình mà lập trình hướng đối tượng được tạo ra để tránh.

Về số dư, tôi muốn chấm cú pháp và thuộc tính chưa bao giờ được giới thiệu. Tôi đã từng có thể nói với mọi người rằng ObjC là một vài phần mở rộng rõ ràng cho C để làm cho nó giống với Smalltalk hơn và tôi không nghĩ điều đó còn đúng nữa.


2

Theo tôi, cú pháp dấu chấm làm cho Objective-C bớt Smalltalk-esque hơn. Nó có thể làm cho mã trông đơn giản hơn, nhưng làm tăng thêm sự mơ hồ. Nó là một struct, unionhoặc đối tượng?


2

Nhiều người dường như đang trộn 'thuộc tính' với 'biến cá thể'. Tôi nghĩ rằng mục đích của các thuộc tính là làm cho nó có thể sửa đổi đối tượng mà không cần phải biết bên trong của nó. Hầu hết thời gian, biến cá thể là 'triển khai' của một thuộc tính (đến lượt nó là 'giao diện'), nhưng không phải lúc nào cũng vậy: đôi khi một thuộc tính không tương ứng với ivar, và thay vào đó nó sẽ tính giá trị trả về ' một cách nhanh chóng'.

Đó là lý do tại sao tôi tin rằng ý tưởng rằng "cú pháp dấu chấm đánh lừa bạn nghĩ rằng bạn đang truy cập vào biến nên nó khó hiểu" là sai. Dấu chấm hoặc dấu ngoặc vuông, bạn không nên đưa ra giả định về nội dung: đó là Thuộc tính, không phải ivar.


Lưu ý thêm, các tham chiếu đối tượng Objective-C không phải là các biến cấu trúc C trực tiếp, mà giống như 'con trỏ đến cấu trúc' hơn, vì vậy cú pháp dấu chấm sẽ không có ý nghĩa khi truy cập trực tiếp vào các thành viên; nó là toán tử mũi tên ->thực hiện vai trò đó (tất nhiên bất cứ khi nào nói rằng các ivars không bị hạn chế truy cập).
Nicolas Miari

1

Tôi nghĩ rằng tôi có thể chuyển sang nhắn tin thay vì ký hiệu dấu chấm vì trong đối tượng head của tôi .instanceVar chỉ là instanceVar thuộc về đối tượng , đối với tôi nó không giống như một cuộc gọi phương thức , vì vậy có thể có những thứ xảy ra trong trình truy cập của bạn và việc bạn sử dụng instanceVar hay self.instanceVar có thể có nhiều sự khác biệt hơn là chỉ ẩn ý so với rõ ràng. Chỉ 2 ¢ của tôi.


1

Ký hiệu dấu chấm cố gắng làm cho các thư trông giống như quyền truy cập vào một thành viên của cấu trúc, mà chúng không phải là quyền truy cập. Có thể hoạt động tốt trong một số trường hợp. Nhưng sẽ sớm có người nghĩ ra một thứ như thế này:

NSView *myView = ...;
myView.frame.size.width = newWidth;

Có vẻ ổn. Nhưng không phải. Nó giống như

[myView frame].size.width = newWidth;

mà không hoạt động. Trình biên dịch chấp nhận cái đầu tiên, nhưng không phải cái thứ hai. Và ngay cả khi nó phát ra một lỗi hoặc cảnh báo đầu tiên, điều này chỉ gây nhầm lẫn.


1

Gọi tôi là lười biếng nhưng nếu tôi phải gõ một cái '.' so với hai [] mỗi lần để có được kết quả giống nhau, tôi thích một lần. Tôi ghét những ngôn ngữ dài dòng. Dấu () trong ngọng khiến tôi phát điên. Ngôn ngữ tao nhã như toán học ngắn gọn và hiệu quả, tất cả những ngôn ngữ khác đều thiếu sót.


1
Vấn đề là Toán học, mặc dù ngắn gọn và hiệu quả, không phải là một ngôn ngữ thông thường và vì vậy chúng ta không thể phân tích cú pháp và biên dịch nó. Lưu ý, ví dụ, trong các hàm toán học, người ta thường viết chúng bằng dấu ngoặc đơn, vì sẽ khó hơn nhiều nếu không có.
jbrennan

1

Sử dụng ký hiệu dấu chấm (bất cứ khi nào bạn có thể)

Trên các phương thức instance trả về một số giá trị

Không sử dụng ký hiệu dấu chấm

Trên các phương thức cá thể trả về void, trên các phương thức init hoặc trên phương thức Lớp.

Và ngoại lệ yêu thích của cá nhân tôi

NSMutableArray * array = @[].mutableCopy;

0

Cá nhân tôi không sử dụng ký hiệu dấu chấm trong mã. Tôi chỉ sử dụng nó trong biểu thức ràng buộc CoreData KVC khi được yêu cầu.

Lý do không sử dụng chúng trong mã đối với tôi là ký hiệu dấu chấm ẩn ngữ nghĩa của setter. Đặt một thuộc tính trong ký hiệu dấu chấm luôn giống như phép gán bất kể ngữ nghĩa của setter (gán / giữ lại / sao chép). Việc sử dụng ký hiệu thông báo làm cho đối tượng nhận có quyền kiểm soát những gì xảy ra trong bộ cài đặt và nhấn mạnh thực tế là những tác động đó cần được xem xét.

Tôi vẫn đang xem xét liệu tôi có thể muốn sử dụng ký hiệu dấu chấm khi truy xuất giá trị của thuộc tính được khai báo hoặc tuân thủ KVC hay không vì nó phải nhỏ gọn và dễ đọc hơn một chút và không có ngữ nghĩa ẩn. Hiện tại, tôi đang gắn bó với ký hiệu tin nhắn vì sự nhất quán.


1
Vẫn có thể có những điều ẩn đang diễn ra. Một getter có thể làm những việc khác ngoài việc chỉ trả về một biến thể hiện. Ngay cả khi nó là một thuộc tính được khai báo, getter không cần phải được tổng hợp hoặc nó có thể đã được ghi đè trong một lớp con.
Sven

-1

OK, ký hiệu dấu chấm trong Objective-C trông rất lạ. Nhưng tôi vẫn không thể làm những việc sau mà không có nó:

int width = self.frame.size.width;

Hoạt động tốt, nhưng:

int height = [[[self frame] size] height];

Cung cấp cho tôi "Không thể chuyển đổi sang loại con trỏ". Tuy nhiên, tôi thực sự muốn giữ cho mã của mình trông nhất quán với ký hiệu tin nhắn.


5
-frame trả về một NSRect, là cấu trúc C, không phải đối tượng Objective-C. Đó là lý do tại sao ví dụ thứ hai gây ra lỗi trình biên dịch. Nó phải là: int height = [self frame] .size.height;

1
Đã đồng ý. Nhưng dấu chấm sau dấu ngoặc trông thật kinh khủng! Tôi thường lưu trữ trực tuyến trong một biến cục bộ trước.
Nicolas Miari

-2

Đây là một câu hỏi tuyệt vời và tôi thấy nhiều câu trả lời khác nhau cho điều này. Mặc dù nhiều người đã đề cập đến các chủ đề, tôi sẽ cố gắng trả lời điều này từ một góc độ khác (một số có thể đã ngầm hiểu):

Nếu chúng ta sử dụng ký hiệu 'dấu chấm', thì việc phân giải mục tiêu cho phương thức được thực hiện tại thời điểm biên dịch. Nếu chúng ta sử dụng tính năng truyền thông báo, thì việc phân giải mục tiêu sẽ bị trì hoãn để thực thi thời gian chạy. Nếu các mục tiêu được giải quyết tại thời điểm biên dịch, thì việc thực thi sẽ nhanh hơn, vì việc giải quyết các mục tiêu tại thời điểm chạy bao gồm một số chi phí. (Không phải là sự khác biệt về thời gian sẽ quan trọng). Vì chúng ta đã xác định thuộc tính trong giao diện của đối tượng, nên không có điểm nào khác biệt về độ phân giải của mục tiêu cho một thuộc tính trong thời gian chạy và do đó ký hiệu dấu chấm là ký hiệu mà chúng ta nên sử dụng để truy cập thuộc tính.


Bạn có biết rằng trong các bộ chọn ObjectiveC trong mọi trường hợp đều được đánh giá, giải quyết và gọi trong thời gian chạy không? Do đó, ký hiệu dấu chấm là một từ đồng nghĩa thuần túy với kiểu dấu ngoặc cũ. Không có bất kỳ khác biệt kỹ thuật nào. Các giả định về tốc độ của bạn rõ ràng là sai - hãy thử nó, sử dụng Instruments và tự xem.
Đế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.