2010-02-01 43 views
17

Tôi muốn thêm bộ chọn vào từ điển (mục đích chính là để xác định phương thức gọi lại và ủy nhiệm sau khi hoàn thành việc gì đó)Thêm công cụ chọn phương thức vào từ điển

Nhưng tôi không thể làm điều đó, chương trình sẽ gặp lỗi "EXC_BAD_ACCESS". Có cách nào khác để tôi thêm bộ chọn phương thức đó vào từ điển không? Cảm ơn sự giúp đỡ của bạn.

Trả lời

22

Thêm một mục mới để một cuốn từ điển không có hai điều (ngoài thêm nó vào từ điển, rõ ràng):

  1. Phải mất một bản sao của giá trị quan trọng. Điều này có nghĩa là đối tượng chính phải triển khai NSCopying giao thức
  2. retain s giá trị. Điều này có nghĩa là cần triển khai giao thức NSObject

Đây có thể là lần thứ hai gây ra EXC_BAD_ACCESS của bạn.

Có ít nhất hai cách để thực hiện việc này.

Thứ nhất, thay vì thêm bộ chọn, bạn có thể thêm thể hiện của lớp thực hiện bộ chọn vào từ điển của bạn. Thông thường lớp học của bạn sẽ kế thừa từ NSObject và nó sẽ hoạt động tốt. Lưu ý rằng nó sẽ giữ lại lớp mặc dù, có thể không phải những gì bạn muốn.

Thứ hai, bạn có thể chuyển đổi bộ chọn thành chuỗi (và ngược lại) bằng cách sử dụng NSSelectorFromStringNSStringFromSelector (docs are here).

+0

Không triển khai phương thức không gây ra EXC_BAD_ACCESS. Bạn nhận được lỗi "không nhận dạng bộ chọn". Thay vào đó, vấn đề là một thực tế rằng các bộ chọn không phải là đối tượng ở tất cả. – user102008

+0

@ user102008 Có, nó bị treo vì chúng không phải là đối tượng. Nhưng nó vẫn không hoạt động đúng nếu các đối tượng không thực hiện 'retain' và' release'. –

1

Thành ngữ phổ biến trong Obj-C là có tên cụ thể cho các cuộc gọi lại cho các sự kiện cụ thể. (Chẳng hạn parserDidBeginDocument: từ NSXMLParserDelegate). Nếu bạn thực sự cần phải có khả năng chỉ định tên, có khả năng là truy vấn duy nhất của bạn là thêm tên của bộ chọn là @"mySelector:withArgument:context:" hoặc somesuch.

+3

Bạn có thể chuyển đổi giữa SEL và NSString bằng NSSelectorFromString và NSStringFromSel ector –

+0

Tôi sử dụng một đối tượng đơn lẻ để truy cập internet. và tôi có một tên phương thức: "getFooWithDelegate: callbackSelector:" và tôi muốn thêm đại biểu và gọi lại vào một từ điển các yêu cầu sử dụng UUID yêu cầu làm khóa. Bạn có thể giải thích thêm về việc thêm "tên của bộ chọn" mà bạn đã đề cập không? – KONG

+0

@athanhcong: một lần nữa; nó thực sự có vẻ như thể bạn nên có một tên cụ thể cho bộ chọn được đề cập, ví dụ: 'internetConnection: receivedFoo: withUUID:', vì bạn sẽ phải viết phương thức nhận để nhận đối tượng khá cụ thể. Nếu lý do đó không phải là một lựa chọn; bạn sẽ sử dụng 'NSSelectorFromString()' và 'NSStringFromSelector()' như được nêu trong bài đăng của Stephen Darlingtons. –

2

tôi nhận được câu trả lời của tôi dựa trên những nhận xét của Zydeco:

Bạn có thể chuyển đổi giữa SEL và NSString sử dụng NSSelectorFromString và NSStringFromSelector

36

Tôi biết câu hỏi này được trả lời một thời gian dài trước đây , nhưng chỉ trong trường hợp bất cứ ai tình cờ gặp nó như tôi đã làm ...

Sự kết hợp của NSStringFromSelectorNSSelectorFromString như ans wered ở trên có lẽ là cách tốt nhất để đi. Nhưng nếu bạn thực sự muốn, bạn có thể sử dụng công cụ chọn làm giá trị hoặc khóa trong một NSDictionary.

Bộ chọn (loại SEL) được triển khai dưới dạng con trỏ trỏ đến cấu trúc trong các thời gian chạy Objective-C của Apple. Một con trỏ không thể được sử dụng trực tiếp trong một từ điển, nhưng một con trỏ có thể được bọc trong một đối tượng NSValue có thể được sử dụng.

Sử dụng phương pháp này, bạn có thể lưu trữ một selector như một giá trị trong một cuốn từ điển sử dụng mã như thế này:

 
dictionary = 
    [NSDictionary dictionaryWithObject:[NSValue valueWithPointer:selector] 
           forKey:key]; 

Một bộ chọn có thể được lấy ra sử dụng mã như thế này:

 
SEL selector = [[dictionary objectForKey:key] pointerValue]; 

Tương tự như vậy cho việc sử dụng công cụ chọn làm khóa:

 
dictionary = 
    [NSDictionary dictionaryWithObject:value 
           forKey:[NSValue valueWithPointer:selector]]; 

value = [dictionary objectForKey:[NSValue valueWithPointer:selector]]; 
+3

+1 sử dụng phương pháp này để lưu trữ khóa là hiệu quả hơn chuyển đổi nó thành một chuỗi vì so sánh con trỏ là O (1) trong khi so sánh chuỗi là O (n) – user102008

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