#ios #delegates
#iOS #делегаты
Вопрос:
В настоящее время я извлекаю список объектов «contest», к которым привязана информация о местоположении. Я хочу следить за всеми соревнованиями, на которых я нахожусь поблизости.
for(Contest *contest in contests) {
NSMutableDictionary * fence1 = [NSMutableDictionary new];
[fence1 setValue:contest.event.name forKey:@"identifier"];
[fence1 setValue:[NSString stringWithFormat:@"%f", contest.location.latitude] forKey:@"latitude"];
[fence1 setValue:[NSString stringWithFormat:@"%f", contest.location.longitude] forKey:@"longitude"];
[fence1 setValue:@"1000" forKey:@"radius"];
//the below method returns a CLRegion object
CLRegion *region = [self dictToRegion:fence1];
//adding custom contest object to region
region.contest = contest;
[self.locationManager requestStateForRegion:region];
}
Я ТАКЖЕ хочу привязать пользовательское свойство contest к региону (как показано в приведенном выше коде), но, похоже, оно не переносится в метод делегирования didDetermineState:
-(void)locationManager:(CLLocationManager *)manager didDetermineState:(CLRegionState)state forRegion:(CLRegion *)region {
switch (state) {
case CLRegionStateUnknown:
NSLog(@"Unknown state!");
break;
case CLRegionStateInside:
NSLog(@"Inside state!");
//this comes back as null
NSLog(@"%@", region.contest.name);
break;
case CLRegionStateOutside:
NSLog(@"Outside state!");
break;
default:
break;
}
}
В методе делегирования region.contest возвращает значение (null). Есть ли лучший подход, который можно использовать?
Приложение (моя категория для CLRegion): CLRegion Contest.h:
#import <CoreLocation/CoreLocation.h>
#import "Event.h"
#import "Contest.h"
@interface CLRegion (Loopd)
@property (nonatomic, strong) Event *event;
@property (nonatomic, strong) Contest *contest;
@end
Регион Конкурс.m:
#import "CLRegion Loopd.h"
#import <objc/runtime.h>
static char defaultHashKey;
@implementation CLRegion (Loopd)
@dynamic event;
@dynamic contest;
-(Event* ) event {
return objc_getAssociatedObject(self, amp;defaultHashKey);
}
- (void) setEvent:(Event *)event {
objc_setAssociatedObject(self, amp;defaultHashKey, event, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
-(Contest* ) contest {
return objc_getAssociatedObject(self, amp;defaultHashKey);
}
- (void) setContest:(Contest *)event {
objc_setAssociatedObject(self, amp;defaultHashKey, event, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
@end
Ответ №1:
С вашей категорией есть 2 проблемы. 1. Вы используете один и тот же ключ для обоих свойств. 2. defaultHashKey инициализируется значением 0.
objc_getAssociatedObject и objc_setAssociatedObject работают в основном как setValue:forKey: и getValueForKey: . Итак, вам нужно предоставить ключ, который привязывает значение к объекту. Попробуйте что-то подобное:
#import "CLRegion Loopd.h"
#import <objc/runtime.h>
static char* kEventKey = "kEventKey";
static char* kContestKey = "kContestKey";
@implementation CLRegion (Loopd)
@dynamic event;
@dynamic contest;
-(Event* ) event {
return objc_getAssociatedObject(self, kEventKey);
}
- (void) setEvent:(Event *)event {
objc_setAssociatedObject(kEventKey, event, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
-(Contest* ) contest {
return objc_getAssociatedObject(self, kContestKey);
}
- (void) setContest:(Contest *)event {
objc_setAssociatedObject(self, kContestKey, event, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
@end
Этот код должен работать, но было бы намного лучше создать отдельный объект для хранения этой ассоциации (я не большой поклонник использования среды выполнения для такого рода целей).
РЕДАКТИРОВАТЬ: вы присваиваете значение для конкурса несколько раз в цикле for. Итак, один из конкурсов (последний) присваивается объекту CLRegion.
Комментарии:
1. так это вообще плохой метод? кстати, я все еще получаю null для связанного объекта.
2. Я подтвердил, что настройка / получение работает с вашим кодом, но в вызываемом методе делегирования объект contest больше не связан с объектом region, возвращенным методом делегирования
3. Я понял, что метод делегирования не возвращает то же самое object…so кажется, нет хорошего способа обойти эту проблему!
4. Это неплохо, если вы на 100% уверены в том, что делаете, и каковы недостатки. Что также может быть неправильным в вашем коде, так это то, что вы присваиваете значение объекта несколько раз. См. Редактирование в моем сообщении.