7

Tôi có một tập hợp các đối tượng thực thể trong cơ sở dữ liệu Dữ liệu cốt lõi iOS của tôi mô tả thứ gì đó tại một vị trí. Hãy gọi thực thể Location. Tôi đã thực hiện điều này bằng cách có hai thuộc tính trên Vị trí đề cập đến vị trí - vĩ độ và kinh độ, cả hai đều tăng gấp đôi. Có những yếu tố khác, như tên.Vị trí trong Dữ liệu chính được sắp xếp theo khoảng cách qua NSFetchedResultsController?

Tôi đang sử dụng NSFetchedResultsController để liên kết các thực thể với UITableViewController. Những gì tôi muốn làm là có kết quả được sắp xếp theo khoảng cách đến một CLLocationCoordinate2D đã cho. Trong một kịch bản thực sự lý tưởng, tôi có thể làm mới danh sách đó để tính toán lại sắp xếp dựa trên vị trí mới. Do đó, sắp xếp này sẽ phụ thuộc vào hai khóa và một biến "tĩnh" thứ ba (biến không thay đổi trên các mục trong bộ sưu tập).

Tôi nghĩ tôi có thể tìm ra cách để thực hiện việc này nếu tôi sắp xếp danh sách tùy ý với NSSortDescriptors. Tuy nhiên, tôi không kiểm soát cách các bộ mô tả sắp xếp được sử dụng trong NSFetchedResultsController.

Có cách nào để tôi có thể định cấu hình các thực thể của mình, NSFetchedResultsController, NSSortDescriptors, v.v. của tôi để thực hiện việc này không? Tôi nghi ngờ rằng câu trả lời không nằm trong việc tạo ra một NSSortDescriptor ưa thích mà thay vào đó trong việc tạo ra một thuộc tính tạm thời trong thực thể đại diện cho khoảng cách-to-me, và tính toán lại thuộc tính đó định kỳ. Tuy nhiên, tôi là đủ mới để Core dữ liệu mà tôi không chắc chắn làm thế nào để tốt nhất làm điều này (iterate trên tất cả các thực thể và tính toán lại một lĩnh vực). Tôi cũng không chắc chắn nếu NSSortDescriptors sẽ làm việc trên các thuộc tính thoáng qua.

+0

Thật không may, bộ điều khiển kết quả được tìm nạp không thể sắp xếp thuộc tính tạm thời hoặc thuộc tính được tính. Xem http://stackoverflow.com/questions/13292582/nspredicate-with-function-not-working hoặc http://stackoverflow.com/questions/12027769/nssortdescriptor-sort-by-location cho các vấn đề tương tự và tham chiếu đến tài liệu. –

+0

Cảm ơn bạn! Tôi thấy cái đó, và đó là lý do tại sao tôi nghĩ rằng câu trả lời có thể là tính toán các giá trị trong các thực thể Core Data của tôi. Hãy tạm thời rời khỏi bảng - nếu nó không phải là một trường thoáng qua, làm thế nào tôi sẽ đi định kỳ cập nhật tập hợp các thực thể? –

+0

Bạn có thực sự cần một bộ điều khiển kết quả tìm nạp không? Nếu bạn lấy các đối tượng vào một mảng, bạn có thể sắp xếp mảng đó trong bộ nhớ và sử dụng làm nguồn dữ liệu cho dạng xem bảng. –

Trả lời

12

(Từ các ý kiến ​​:)

Một lấy yêu cầu cho một (SQLite dựa) lưu trữ dữ liệu cốt lõi không thể sử dụng loại mô tả dựa trên thuộc tính thoáng qua hoặc vị dựa-C Mục tiêu.

Nếu bạn không muốn mất ưu điểm của bộ điều khiển kết quả tìm nạp (như cập nhật chế độ xem bảng động, nhóm tự động thành các phần, v.v.) bạn phải tính toán trước khoảng cách tới vị trí hiện tại và lưu trữ nó trong (persistent) thuộc tính của đối tượng của bạn.

Hoặc, bạn có thể tìm nạp tất cả các đối tượng và sắp xếp chúng trong bộ nhớ. Trong trường hợp đó, bạn có thể sử dụng các bộ mô tả sắp xếp tùy ý. Nhưng điều đó không thể được kết hợp với một bộ điều khiển kết quả tìm nạp, vì vậy bạn sẽ phải đăng ký các thay đổi trong bối cảnh đối tượng được quản lý và tải lại bảng nếu cần thiết.

0

Tôi phát hiện ra BSFetchedResultsController github project là lớp con NSFetchResultsController thực hiện những gì Martin đề xuất ở chỗ nó sắp xếp trong bộ nhớ bằng cách sử dụng một bộ mô tả sắp xếp tùy ý, nó cũng đăng ký thay đổi ngữ cảnh và tính toán bất kỳ thay đổi chỉ mục nào. bộ mô tả sắp xếp. Tất cả trong một kỳ công rất ấn tượng! Tôi thành công sử dụng nó để sắp xếp theo khoảng cách như sau:

BSFetchedResultsController* fetchedResultsController = [[BSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:managedObjectContext sectionNameKeyPath:nil cacheName:nil]; 

// create a location to compare distance to, e.g. current location 
CLLocation* sourceLocation = [[CLLocation alloc] initWithLatitude:55.87595153937809 longitude:-4.2578177698913855]; 

// compare the distance from both to the source location 
fetchedResultsController.postFetchComparator= ^(id a, id b) { 
    Venue* v1 = (Venue*)a; 
    Venue* v2 = (Venue*)b; 

    double d1 = [v1.coreLocation distanceFromLocation:sourceLocation]; 
    double d2 = [v2.coreLocation distanceFromLocation:sourceLocation]; 

    return [@(d1) compare:@(d2)]; 
}; 

NSError *error = nil; 
if (![fetchedResultsController performFetch:&error]) { 
    NSLog(@"Unresolved error %@, %@", error, [error userInfo]); 
} 

Từ một dự án cũ của mình nó không có ARC, vì vậy khi bạn bao gồm hai tập tin nhớ để đánh dấu .m với trình biên dịch Flags -fno-objc -arc trong Target, Build Phases. Ngoài ra, hãy lưu ý rằng nhà phát triển cho rằng mã không phải là sản phẩm đã sẵn sàng để đảm bảo thực hiện kiểm tra đầy đủ nếu sử dụng nó.

Trong mã của tôi ở trên, tôi có thuộc tính coreLocation tạm thời trên lớp con đối tượng được quản lý Địa điểm của tôi, bạn có thể xem cách đạt được điều đó here. Ngoài ra tính toán khoảng cách là không hiệu quả, bạn có thể muốn bộ nhớ cache khoảng cách trong đối tượng hơn là tính lại nó mỗi so sánh.

Cuối cùng, xuất hiện dự án này là do câu hỏi Stackoverflow của người sáng tạo Daniel Thorpe không giải đáp được, khiến anh ấy giải quyết vấn đề và tự đăng câu trả lời, nên tôi nghĩ nếu bạn thấy dự án của mình hữu ích, bạn có thể vui lòng up-vote his post như tôi đa lam.

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