проблемы с созданием постоянного объекта в Objective C

StackOverflow https://stackoverflow.com/questions/2402124

  •  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"

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top