Objective-C在其他方法中使用NSString

时间:2023-01-15 23:01:18

I have a problem and I don't know how to fix it.

我有一个问题,我不知道如何解决它。

Viewcontroller.m

Viewcontroller.m

-(void)application:(UIApplication *)application     didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
NSLog(@"APN device token: %@", deviceToken);
NSString *deviceTokenString = [NSString stringWithFormat:@"%@",deviceToken];
}

- (void)viewDidLoad
{
NSMutableURLRequest *request =[NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"http://www.domain.com/blabla.php"]];
[request setHTTPMethod:@"POST"];

NSString *post =[[NSString alloc] initWithFormat:@"udid=%@&submit=",deviceTokenString];
[request setHTTPBody:[post dataUsingEncoding:NSUTF8StringEncoding]];

NSURLResponse *response;
NSError *err;
NSData *responseData = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&err];

[super viewDidLoad];
}

I want the deviceTokenString from application didRegisterForRemoteNotificationsWithDeviceToken to viewDidLoad in the post but it won't work.

我希望将来自应用程序didRegisterForRemoteNotificationsWithDeviceToken的deviceTokenString发布到postDidLoad中,但它不起作用。

When I have this code in ViewController.h

当我在ViewController.h中有这个代码时

@interface ViewController : UIViewController {
NSString *deviceTokenString;
}

@property(nonatomic, retain) NSString *deviceTokenString;

it only returns "Null" and not the deviceToken

它只返回“Null”而不是deviceToken

I hope someone can help me :)

我希望有一个人可以帮助我 :)

3 个解决方案

#1


1  

You're dealing with two different classes, your UIApplication's delegate class and a UIViewController class. Instance variables defined in one class are not exposed to other classes by default, unless they are also defined as properties of the class.

您正在处理两个不同的类,UIApplication的委托类和UIViewController类。默认情况下,在一个类中定义的实例变量不会向其他类公开,除非它们也被定义为类的属性。

In your case, you've defined a property on the View Controller class for your deviceTokenString object. So, you've exposed this property of the View Controller to other classes that might be interested in accessing this object.

在您的情况下,您已在View Controller类中为deviceTokenString对象定义了一个属性。因此,您已将View Controller的此属性公开给可能对访问此对象感兴趣的其他类。

Inside your UIApplicationDelegate object, in the didReceiveRemote... method, a NSString object is passed in for you by the system with the parameter name deviceToken. When you receive this object, you don't need to do any other operations on it (ie stringWithFormat:).

在UIApplicationDelegate对象中,在didReceiveRemote ...方法中,系统使用参数名称deviceToken为您传入NSString对象。当您收到此对象时,您不需要对其执行任何其他操作(即stringWithFormat :)。

What you might or might not encounter in your app is something called a race condition. viewDidLoad might happen before your app receives the didReceiveToken message. Be wary of this.

您在应用程序中可能遇到或未遇到的内容称为竞争条件。 viewDidLoad可能会在您的应用收到didReceiveToken消息之前发生。警惕这一点。

To solve your problem, what you should do is access your viewController object in the didReceiveRemote... method, like so:

要解决您的问题,您应该做的是访问didReceiveRemote ...方法中的viewController对象,如下所示:

-(void)didReceiveToken... {
      UIViewController *myViewController = self.viewController; //how do you initially set up this object?
      myViewController.deviceTokenString = deviceToken;
}

Not saying that this is the best way to do it, but it will solve your problem. Also leaves other things out, like what happens when you set the property. Doing it in viewDidLoad is an easy way to do things automatically. A way around this is to use Key-Value-Observing, which is another question/tutorial in itself.

不是说这是最好的方法,但它会解决你的问题。还要留下其他东西,比如设置属性时会发生什么。在viewDidLoad中执行此操作是一种自动执行操作的简便方法。解决这个问题的方法是使用Key-Value-Observing,这本身就是另一个问题/教程。

GOod luck.

祝你好运。

#2


1  

it only returns "Null" and not the deviceToken

它只返回“Null”而不是deviceToken

That's because you've declared a local variable with the same name as your instance variable. In -application:didRegisterForRemoteNotificationsWithDeviceToken: you've got:

那是因为你已经声明了一个与你的实例变量同名的局部变量。在-application:didRegisterForRemoteNotificationsWithDeviceToken:你有:

NSString *deviceTokenString = [NSString stringWithFormat:@"%@",deviceToken];

which creates a local variable named deviceTokenString. That variable goes away as soon as the method exits. You never set the instance variable, so when you try to access that in -viewDidLoad you get nil.

它创建一个名为deviceTokenString的局部变量。一旦方法退出,该变量就会消失。您永远不会设置实例变量,所以当您尝试在-viewDidLoad中访问它时,您将获得nil。

To fix the problem, simply change the line above to:

要解决此问题,只需将上面的行更改为:

deviceTokenString = [NSString stringWithFormat:@"%@",deviceToken];

Now you're using the deviceTokenString that is your instance variable, so the value will be assigned to the ivar and will persist beyond the end of the method.

现在您正在使用作为实例变量的deviceTokenString,因此该值将分配给ivar,并将持续超出方法的末尾。

#3


0  

You are redeclaring the NSString deviceTokenString in the -(void)application function. That local declaration supersedes the property declared in the interface. So when that application function goes out of scope, the NSString object you created (which is on the stack) is no longer existent.

您正在重新声明 - (void)应用程序函数中的NSString deviceTokenString。该本地声明取代接口中声明的属性。因此,当该应用程序函数超出范围时,您创建的NSString对象(在堆栈中)不再存在。

Remove the NSString * from the -(void)application function

从 - (void)应用程序函数中删除NSString *

-(void)application:(UIApplication *)application    
    didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {

      NSLog(@"APN device token: %@", deviceToken);
      deviceTokenString = [NSString stringWithFormat:@"%@",deviceToken];
}

This should fix your issue

这应该可以解决您的问题

#1


1  

You're dealing with two different classes, your UIApplication's delegate class and a UIViewController class. Instance variables defined in one class are not exposed to other classes by default, unless they are also defined as properties of the class.

您正在处理两个不同的类,UIApplication的委托类和UIViewController类。默认情况下,在一个类中定义的实例变量不会向其他类公开,除非它们也被定义为类的属性。

In your case, you've defined a property on the View Controller class for your deviceTokenString object. So, you've exposed this property of the View Controller to other classes that might be interested in accessing this object.

在您的情况下,您已在View Controller类中为deviceTokenString对象定义了一个属性。因此,您已将View Controller的此属性公开给可能对访问此对象感兴趣的其他类。

Inside your UIApplicationDelegate object, in the didReceiveRemote... method, a NSString object is passed in for you by the system with the parameter name deviceToken. When you receive this object, you don't need to do any other operations on it (ie stringWithFormat:).

在UIApplicationDelegate对象中,在didReceiveRemote ...方法中,系统使用参数名称deviceToken为您传入NSString对象。当您收到此对象时,您不需要对其执行任何其他操作(即stringWithFormat :)。

What you might or might not encounter in your app is something called a race condition. viewDidLoad might happen before your app receives the didReceiveToken message. Be wary of this.

您在应用程序中可能遇到或未遇到的内容称为竞争条件。 viewDidLoad可能会在您的应用收到didReceiveToken消息之前发生。警惕这一点。

To solve your problem, what you should do is access your viewController object in the didReceiveRemote... method, like so:

要解决您的问题,您应该做的是访问didReceiveRemote ...方法中的viewController对象,如下所示:

-(void)didReceiveToken... {
      UIViewController *myViewController = self.viewController; //how do you initially set up this object?
      myViewController.deviceTokenString = deviceToken;
}

Not saying that this is the best way to do it, but it will solve your problem. Also leaves other things out, like what happens when you set the property. Doing it in viewDidLoad is an easy way to do things automatically. A way around this is to use Key-Value-Observing, which is another question/tutorial in itself.

不是说这是最好的方法,但它会解决你的问题。还要留下其他东西,比如设置属性时会发生什么。在viewDidLoad中执行此操作是一种自动执行操作的简便方法。解决这个问题的方法是使用Key-Value-Observing,这本身就是另一个问题/教程。

GOod luck.

祝你好运。

#2


1  

it only returns "Null" and not the deviceToken

它只返回“Null”而不是deviceToken

That's because you've declared a local variable with the same name as your instance variable. In -application:didRegisterForRemoteNotificationsWithDeviceToken: you've got:

那是因为你已经声明了一个与你的实例变量同名的局部变量。在-application:didRegisterForRemoteNotificationsWithDeviceToken:你有:

NSString *deviceTokenString = [NSString stringWithFormat:@"%@",deviceToken];

which creates a local variable named deviceTokenString. That variable goes away as soon as the method exits. You never set the instance variable, so when you try to access that in -viewDidLoad you get nil.

它创建一个名为deviceTokenString的局部变量。一旦方法退出,该变量就会消失。您永远不会设置实例变量,所以当您尝试在-viewDidLoad中访问它时,您将获得nil。

To fix the problem, simply change the line above to:

要解决此问题,只需将上面的行更改为:

deviceTokenString = [NSString stringWithFormat:@"%@",deviceToken];

Now you're using the deviceTokenString that is your instance variable, so the value will be assigned to the ivar and will persist beyond the end of the method.

现在您正在使用作为实例变量的deviceTokenString,因此该值将分配给ivar,并将持续超出方法的末尾。

#3


0  

You are redeclaring the NSString deviceTokenString in the -(void)application function. That local declaration supersedes the property declared in the interface. So when that application function goes out of scope, the NSString object you created (which is on the stack) is no longer existent.

您正在重新声明 - (void)应用程序函数中的NSString deviceTokenString。该本地声明取代接口中声明的属性。因此,当该应用程序函数超出范围时,您创建的NSString对象(在堆栈中)不再存在。

Remove the NSString * from the -(void)application function

从 - (void)应用程序函数中删除NSString *

-(void)application:(UIApplication *)application    
    didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {

      NSLog(@"APN device token: %@", deviceToken);
      deviceTokenString = [NSString stringWithFormat:@"%@",deviceToken];
}

This should fix your issue

这应该可以解决您的问题