2009-06-17 30 views
9

Trong Mục tiêu C, có một lớp lót hay một thứ gì đó nhỏ để loại bỏ (rút ngắn một) và trả lại phần tử đầu tiên của một mảng, bất kể chỉ mục của nó là gì?Làm thế nào tôi có thể loại bỏ phần tử đầu tiên của một mảng trong Mục tiêu C?

+0

Bạn đang nói về một mảng kiểu C trần, hoặc một cái gì đó giống như một NSArray/NSMutableArray? –

+1

Trong trường hợp của một mảng kiểu C trần bạn đang gặp rắc rối trước khi bạn ra khỏi cổng: các mảng kiểu C không bao gồm các giới hạn của chúng/thông tin kích thước hợp lệ. Tôi cho rằng bạn có thể vượt qua một con trỏ đến kích thước hợp lệ, nhưng điều đó trở nên xấu xí ... –

+1

Sau đó, một lần nữa, đối với một mảng kiểu C, * p ++ thực hiện một điều gì đó giống như một sự thay đổi. –

Trả lời

19

Tôi không biết phương thức trả về mục bị xóa nhưng bạn có thể thực hiện việc này bằng cách kết hợp NSArray#objectAtIndex:0NSMutableArray#removeObjectAtIndex:0. Tôi cho rằng bạn có thể giới thiệu một loại phương pháp mới trên NSMutableArray thực hiện phương thức shift.

+0

Tôi đã được ấn tượng rằng khi tôi removeObjectAtIndex: 0 Tôi sẽ được trái với một mảng mà bắt đầu với một chỉ số 1, như bạn có thể tìm thấy trong PHP. Nhưng khi nó quay ra, chạm vào cái đó (nó là lâu đời nhất mà tôi đã thêm vào mảng) là đủ cho những gì tôi đang làm. – ojreadmore

+1

Tài liệu được liên kết cho biết nó hoạt động tương tự như thay đổi, trượt các phần tử khác xuống. –

+0

Nếu bạn thực sự muốn có một cuộc gọi phương thức duy nhất, hãy xem câu trả lời của tôi cho một tuyên bố danh mục mẫu để thêm những gì bạn cần. –

1

Đối tượng mảng ca cao (NSArray/NSMutableArray) không cung cấp một dòng tương đương - trước tiên bạn sẽ phải đọc đối tượng, sau đó xóa đối tượng đó. Thực tế là các lớp này cung cấp các phương pháp -lastObject-removeLastObject nhưng không phải -firstObject-removeFirstObject phải là lời nhắc rằng việc xóa khỏi mặt trước của mảng thường là hoạt động không hiệu quả, vì nội dung phải được dịch chuyển (sao chép) một vị trí tiến lên. Điều này đặc biệt đúng với các mảng trong C, được gắn với con trỏ.

Nếu bạn đang làm việc với bất kỳ thứ gì ngoài các kiểu dữ liệu nguyên thủy và/hoặc các mảng rất nhỏ, bạn có thể muốn xem xét rằng hành vi "chuyển dịch" phần tử đầu tiên là chỉ thị của queue data structure. Để biết chi tiết về cách bạn có thể tạo hàng đợi cho các đối tượng, hãy xem this SO question. Cá nhân, my opinion for that question là một lớp hàng đợi thực sự cung cấp thành ngữ lập trình rõ ràng nhất. Bạn thậm chí có thể xác định phương pháp riêng của bạn (có lẽ như một phạm trù trên NSMutableArray hoặc lớp khác) mà không cung cấp một lớp lót để làm những gì bạn muốn:

@interface NSMutableArray (QueueOneLiner) 
    - (id) removeAndReturnFirstObject; // Verbose, but clearer than "shift" 
@end 

@implementation NSMutableArray (QueueOneLiner) 
    - (id) removeAndReturnFirstObject { 
    id object = [[self objectAtIndex:0] retain]; 
    [self removeObjectAtIndex:0]; 
    return [object autorelease]; 
    } 
@end 

Tuy nhiên, bởi thời điểm đó là giải pháp rất có thể sẽ gây ra chi phí cao hơn giá trị của nó, tùy thuộc vào mức độ quan trọng bạn đặt trên sự đơn giản so với hiệu suất của mã sử dụng nó.

+1

QueueOneLiner của bạn có thể trả về một đối tượng không hợp lệ. Các removeObjectAtIndex: 0 sẽ phát hành "đối tượng" mà có thể sớm deallocate nó nếu thu gom rác thải không được sử dụng. Bạn nên giữ lại và sau đó autorelease đối tượng trước khi loại bỏ nó khỏi mảng. – dreamlax

+0

Một điểm tuyệt vời! Đã chỉnh sửa để bao gồm đề xuất của bạn. –

3

Đó sẽ là một điều tồi tệ để làm.

Objective-C trên iPhone thực sự có thể sử dụng hầu hết các đặc quyền thực hiện C.

Nếu bạn nhìn vào một số bài viết khác của tôi, bạn sẽ thấy tôi cương quyết chống lại tối ưu hóa quá sớm, nhưng khi bạn đang mã hóa ở cấp độ C, chỉ có một số điều bạn không làm không cần thiết.

  • Move nhớ
  • cấu trúc Duplicate
  • phân bổ dân cư thưa thớt khối bộ nhớ
  • Inner vòng
  • ... (Có rất nhiều hơn, nhưng C-cuộc sống của tôi là Rusty và, như tôi đã nói , Tôi chống tối ưu hóa)

Điều bạn có thể muốn là hàng đợi được triển khai tốt. Một cái gì đó mà phân bổ trước một cấu trúc bộ nhớ tròn đủ lớn và sau đó có hai con trỏ theo dõi byte đầu tiên và cuối cùng.

Tôi rất ngạc nhiên khi biết rằng Objective-C không có cấu trúc dữ liệu hàng đợi.

Ngoài ra, đừng cố gắng cho một lớp lót. Tất cả nội dung về mã terse đều bị đánh giá quá cao. Nếu nó có ý nghĩa hơn để gọi một phương pháp, vì vậy hãy là nó.

+0

perl "mảng" giống như một hàng đợi được triển khai tốt hơn so với mảng C; họ đã lưu trữ offsets để "đầu tiên" và các yếu tố cuối cùng và preallocate thông minh khi cần thiết. – ysth

+0

Tất cả các lý do khác để sử dụng một Hàng đợi trên Mục tiêu-C sau đó. Hầu hết các ngôn ngữ thông dịch đều chậm hơn 100 lần so với các ngôn ngữ biên dịch - ở tốc độ đó, các mối quan tâm hoàn toàn khác và hoàn toàn có ý nghĩa rằng tất cả các mảng sẽ có chi phí của hàng đợi, nhưng bạn sẽ không tìm thấy bất kỳ thứ gì giống như vậy trong C ngôn ngữ dựa trên. –

1

Nếu bạn có một mảng obj *arr trong đó obj là một lớp/tên tệp và arr là mảng, bạn chỉ có thể nói arr+1 để lấy mảng mà không có phần tử đầu tiên.

0

Sử dụng mã này,

[arrayName removeObjectAtIndex:0]; 

này có thể giúp bạn

+0

Điều này không cung cấp bất kỳ thông tin hữu ích bổ sung nào mà câu trả lời được chấp nhận chưa cung cấp và sẽ chỉ hoạt động trong trường hợp 'NSMutableArray' (không phải' NSArray') – Stonz2

0

Đó chắc chắn là quá muộn để hỗ trợ các poster ban đầu, nhưng nếu bạn có một NSArray đơn giản và không phải là một NSMutableArray, này hoạt động tốt:

id myData = myArray.firstObject; 
myArray = [myArray subarrayWithRange:NSMakeRange(1, myArray.count - 1)]; 
+0

Trừ khi mảng của bạn chỉ có một mục trong đó, trong trường hợp đó giá trị 'loc' của 1 nằm ngoài' NSArray' và bạn ném một 'NSRangeException' – SDJMcHattie

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