问题使 Objective C 中的持久对象成为可能

发布于 2024-08-23 20:46:50 字数 1375 浏览 10 评论 0原文

尝试创建一个名为“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

应用程序的不同部分需要该对象设置器和获取器。我一直在尝试像这样访问它们

Person * ThePerson = [[Person alloc] init];
ThePerson = nil;
NSString * PersonsName;
PersonsName = [[Person sharedInstance] firstName];

一切在登录屏幕上都运行良好,但在下次使用时就会消失。通常是 EXC_BAD_ACCESS(哎呀!)。

显然我在这里做了一些非常错误的事情。是否有更简单的方法在不同的视图控制器(编码和 xib)之间共享对象?

Attempting to make a NSObject called 'Person' that will hold the login details for my application (nothing to fancy). The app is made of a navigation controller with multiple table views but I am having issues sharing the Person object around.

Attempted to create a static object like this:

+ (Person *)sharedInstance {
    static Person *sharedInstance;
    @synchronized(self) {
        if(!sharedInstance)
            sharedInstance = [[Person alloc] init];
        return sharedInstance;
    }
    return nil;
}

And here is the header

// 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

This object setters and getters are needed in different parts of the application. I have been attempting to access them like this

Person * ThePerson = [[Person alloc] init];
ThePerson = nil;
NSString * PersonsName;
PersonsName = [[Person sharedInstance] firstName];

Everything works well at the login screen but it dies at the next use. usually EXC_BAD_ACCESS (eek!).

Clearly I am doing something very wrong here. Is there an easier way to share objects between different a number view controllers (both coded and xib)?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

○愚か者の日 2024-08-30 20:46:50

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

Why not store this information in the NSUserDefaults or the Keychain?

少女净妖师 2024-08-30 20:46:50

当您的 +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: 消息:方法。

Your +sharedInstance method returns nil when it should be returning the shared instance. Also, I doubt there's any value to synchronizing on that block. The method could be written more simply:

+ (Person *)sharedInstance {
    static Person *sharedInstance;
    if(!sharedInstance) {
        sharedInstance = [[Person alloc] init];
    }
    return sharedInstance;
}

Note that this does not create a 'static object', since there's no such thing in Objective-C; it just assigns an object to a static variable (probably what you meant, but just wanted to make sure).

Another way to share an object among two or more view controllers within a navigation controller is to add a property to the nested view controllers, and call the setter method before navigating. For example, you could add a property such as the following:

@property (nonatomic, retain) Book *book;

to a child of the root view controller, and send it a -setBook: message in the root view controller's -tableView:didSelectRowAtIndexPath: method.

北陌 2024-08-30 20:46:50

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

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

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

另外,我刚刚重新阅读了你的代码,并遇到了一些WTF:

Person * ThePerson = [[Person alloc] init];
ThePerson = nil;

这是怎么回事?那是内存泄漏,就在那里。

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

You're not using the shared instance pattern correctly. Your sharedInstance method should alloc and init a new Person (if it has not already been done once) and assign it to the sharedInstance static variable.

Then when you need a pointer to the person, you should use the shared instance class method, not alloc and init a new instance yourself.

Technically, if you're going for a full blown singleton, your alloc method shouldn't allow you create a new instance of a Person.

Also, I just re-read your code, and came across a bit of a WTF:

Person * ThePerson = [[Person alloc] init];
ThePerson = nil;

What is that all about? That's a memory leak, right there.

All your problems can be solved by replacing any and all lines of Person *thePerson = [[Person alloc] init]; with Person *person = [Person sharedInstance];

悲喜皆因你 2024-08-30 20:46:50

你的 init 很新,如果你想设置 Person 的firstName,可以这样做

Person *thePerson = [Person sharedInstance];  
thePerson.name = @"John Public";

来获取名称,

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

这将在 #imports "Person.h" 的任何类中工作

Your init is hinky, if you want to set the firstName of Person do it like this

Person *thePerson = [Person sharedInstance];  
thePerson.name = @"John Public";

to get the name out,

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

That will work in any class that #imports "Person.h"

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文