Iphone 问题使对象成为目标C中的持久对象

Iphone 问题使对象成为目标C中的持久对象,iphone,objective-c,nsobject,Iphone,Objective C,Nsobject,试图创建一个名为“Person”的NSObject,它将保存我的应用程序的登录详细信息(没什么可想象的)。该应用程序由一个导航控制器和多个表视图组成,但我在共享Person对象时遇到问题 试图创建如下静态对象: + (Person *)sharedInstance { static Person *sharedInstance; @synchronized(self) { if(!sharedInstance) sharedInstance

试图创建一个名为“Person”的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
在登录屏幕上一切正常,但在下次使用时就会消失。通常情况下会出现错误访问(eek!)


很明显,我在这里做错了什么。是否有更简单的方法在不同的a数字视图控制器(编码和xib)之间共享对象?

为什么不将此信息存储在
NSUserDefaults
或钥匙链中?

为什么不将此信息存储在
NSUserDefaults
或钥匙链中?

您没有正确使用共享实例模式。您的sharedInstance方法应该alloc并初始化一个新的Person(如果还没有完成一次),并将其分配给sharedInstance静态变量

然后,当您需要指向此人的指针时,应该使用共享实例类方法,而不是alloc并自己初始化一个新实例

从技术上讲,如果你想要一个完整的单例,你的alloc方法不应该允许你创建一个新的Person实例

另外,我刚刚重新阅读了您的代码,发现了一点WTF:

Person * ThePerson = [[Person alloc] init];
ThePerson = nil;
这是怎么回事?这是内存泄漏,就在那里


您的所有问题都可以通过替换
Person*thePerson=[[Person alloc]init]的任何和所有行来解决
Person*Person=[Person sharedInstance]

您没有正确使用共享实例模式。您的sharedInstance方法应该alloc并初始化一个新的Person(如果还没有完成一次),并将其分配给sharedInstance静态变量

然后,当您需要指向此人的指针时,应该使用共享实例类方法,而不是alloc并自己初始化一个新实例

从技术上讲,如果你想要一个完整的单例,你的alloc方法不应该允许你创建一个新的Person实例

另外,我刚刚重新阅读了您的代码,发现了一点WTF:

Person * ThePerson = [[Person alloc] init];
ThePerson = nil;
这是怎么回事?这是内存泄漏,就在那里


您的所有问题都可以通过替换
Person*thePerson=[[Person alloc]init]的任何和所有行来解决
Person*Person=[Person sharedInstance]

您的init很可疑,如果您想设置Person的名字,请这样做

Person * ThePerson = [[Person alloc] init];
ThePerson = nil;
NSString * PersonsName;
PersonsName = [[Person sharedInstance] firstName];
Person *thePerson = [Person sharedInstance];  
thePerson.name = @"John Public";
为了把名字传出去

NSString *personName = [[Person sharedInstance] name];  

这在任何导入“Person.h”的类中都会起作用。

如果您想设置Person的名字,可以这样做

Person * ThePerson = [[Person alloc] init];
ThePerson = nil;
NSString * PersonsName;
PersonsName = [[Person sharedInstance] firstName];
Person *thePerson = [Person sharedInstance];  
thePerson.name = @"John Public";
为了把名字传出去

NSString *personName = [[Person sharedInstance] name];  

这将在导入“Person.h”的任何类中工作

您的
+sharedInstance
方法在返回共享实例时返回
nil
。而且,我怀疑在那个块上同步有什么价值。该方法可以写得更简单:

+ (Person *)sharedInstance {
    static Person *sharedInstance;
    if(!sharedInstance) {
        sharedInstance = [[Person alloc] init];
    }
    return sharedInstance;
}
注意,这不会创建“静态对象”,因为Objective-C中没有这样的东西;它只是将一个对象分配给一个静态变量(可能是您的意思,但只是想确定一下)

在导航控制器中的两个或多个视图控制器之间共享对象的另一种方法是向嵌套视图控制器添加属性,并在导航之前调用setter方法。例如,可以添加如下属性:

@property (nonatomic, retain) Book *book;

发送到根视图控制器的子级,并在根视图控制器的
-tableView:didSelectRowAtIndexPath:
方法中向其发送
-setBook:
消息。

您的
+sharedInstance
方法应返回共享实例时返回
nil
。而且,我怀疑在那个块上同步有什么价值。该方法可以写得更简单:

+ (Person *)sharedInstance {
    static Person *sharedInstance;
    if(!sharedInstance) {
        sharedInstance = [[Person alloc] init];
    }
    return sharedInstance;
}
注意,这不会创建“静态对象”,因为Objective-C中没有这样的东西;它只是将一个对象分配给一个静态变量(可能是您的意思,但只是想确定一下)

在导航控制器中的两个或多个视图控制器之间共享对象的另一种方法是向嵌套视图控制器添加属性,并在导航之前调用setter方法。例如,可以添加如下属性:

@property (nonatomic, retain) Book *book;

到根视图控制器的子级,并在根视图控制器的
-tableView:didSelectRowAtIndexPath:
方法中向其发送一条
-setBook:
消息。

使用调试器运行,查看它在何处消亡以及是什么导致EXC\u坏访问?在使用调试器运行之前,构建和分析作为对初始化行的快速检查。构建和分析?现在我明白你的意思了。EXC_BAD_ACCESS是由于第二次访问Person对象而导致的。他的意思是,在Xcode中,转到Build菜单并选择Build and Analyze。这将运行Clang静态分析器,它将在代码中提供有关内存管理(和其他)问题的信息非常有用的功能,感谢您指出。使用调试器运行,看看它在哪里消亡,以及是什么导致EXC_BAD_访问失败?在使用调试器运行之前,生成并分析作为对初始化行的快速检查。生成并分析?现在我明白你的意思了。EXC_BAD_ACCESS是由于第二次访问Person对象而导致的。他的意思是,在Xcode中,转到Build菜单并选择Build and Analyze。这将运行Clang静态分析器,它将在代码中提供有关内存管理(和其他)问题的信息非常有用的功能,感谢您指出。以这种方式更改sharedInstance没有任何区别。就在返回nil之前,我添加了一个NSLog,看看它是否曾经返回过nil,但没有。以这种方式更改sharedInstance没有任何区别。J