проблемы с созданием постоянного объекта в Objective C
-
18-09-2019 - |
Вопрос
Попытка создать NSObject под названием «Человек», который будет хранить данные для входа в мое приложение (ничего особенного).Приложение состоит из навигационного контроллера с несколькими табличными представлениями, но у меня возникают проблемы с совместным использованием объекта Person.
Попытка создать статический объект следующим образом:
+ (Person *)sharedInstance {
static Person *sharedInstance;
@synchronized(self) {
if(!sharedInstance)
sharedInstance = [[Person alloc] init];
return sharedInstance;
}
return nil;
}
А вот заголовок
// Person.h
#import <Foundation/Foundation.h>
@interface Person : NSObject {
NSString *fullName;
NSString *firstName;
NSString *lastName;
NSString *mobileNumber;
NSString *userPassword;
}
@property(nonatomic, retain) NSString *fullName;
@property(nonatomic, retain) NSString *firstName;
@property(nonatomic, retain) NSString *lastName;
@property(nonatomic, retain) NSString *mobileNumber;
@property(nonatomic, retain) NSString *userPassword;
+ (Person *)sharedInstance;
-(BOOL) setName:(NSString*) fname;
-(BOOL) setMob:(NSString*) mnum;
-(BOOL) setPass:(NSString*) pwd;
@end
Эти установщики и геттеры объектов необходимы в разных частях приложения.Я пытался получить к ним доступ вот так
Person * ThePerson = [[Person alloc] init];
ThePerson = nil;
NSString * PersonsName;
PersonsName = [[Person sharedInstance] firstName];
На экране входа в систему все работает хорошо, но при следующем использовании оно умирает.обычно EXC_BAD_ACCESS (эй!).
Очевидно, что я делаю здесь что-то очень неправильное.Есть ли более простой способ совместного использования объектов между различными контроллерами числового представления (как закодированными, так и xib)?
Решение
Почему бы не сохранить эту информацию в NSUserDefaults
или брелок?
Другие советы
Твой +sharedInstance
метод возвращает nil
когда он должен возвращать общий экземпляр.Кроме того, я сомневаюсь, что синхронизация этого блока имеет какую-либо ценность.Метод можно было бы записать проще:
+ (Person *)sharedInstance {
static Person *sharedInstance;
if(!sharedInstance) {
sharedInstance = [[Person alloc] init];
}
return sharedInstance;
}
Обратите внимание: при этом не создается «статический объект», поскольку в Objective-C такого нет;он просто присваивает объект статической переменной (вероятно, вы это имели в виду, но просто хотели убедиться).
Другой способ совместного использования объекта между двумя или более контроллерами представления в контроллере навигации — добавить свойство к вложенным контроллерам представления и вызвать метод установки перед навигацией.Например, вы можете добавить такое свойство, как следующее:
@property (nonatomic, retain) Book *book;
дочернему элементу контроллера корневого представления и отправьте ему -setBook:
сообщение в корневом контроллере представления -tableView:didSelectRowAtIndexPath:
метод.
Вы неправильно используете шаблон общего экземпляра.Ваш метод ShareInstance должен выделить и инициализировать нового Person (если это еще не было сделано один раз) и назначить его статической переменной SharedInstance.
Затем, когда вам понадобится указатель на человека, вам следует использовать метод класса общего экземпляра, а не выделять и инициализировать новый экземпляр самостоятельно.
Технически, если вы собираетесь использовать полноценный синглтон, ваш метод alloc не должен позволять вам создавать новый экземпляр Person.
Кроме того, я только что перечитал ваш код и наткнулся на что-то вроде WTF:
Person * ThePerson = [[Person alloc] init];
ThePerson = nil;
Что это вообще такое?Вот это утечка памяти, вот тут.
Все ваши проблемы можно решить заменой любых строк Person *thePerson = [[Person alloc] init];
с Person *person = [Person sharedInstance];
Ваша инициализация странная, если вы хотите установить первое имя человека, сделайте это вот так
Person *thePerson = [Person sharedInstance];
thePerson.name = @"John Public";
чтобы узнать имя,
NSString *personName = [[Person sharedInstance] name];
Это будет работать в любом классе, который #imports "Person.h"