Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Post
  • Reply
pokeyman
Nov 26, 2006

That elephant ate my entire platoon.

pokeyman posted:

(Though I seem to remember something about hidden audio tags not actually playing on iOS, could be making that up though. If I'm right about this, you could have the page notify the app to start playing something, and the app can update the page on its status.)

Oh, and I looked this up, and video/audio tags can only be started through JavaScript as the result of a user-initiated event. So putting onLoad="audio.play()" won't do anything, but onClick="audio.play()" is all good. (Source: Safari HTML5 Audio and Video Guide, very handy, hit it up if you haven't.)

Adbot
ADBOT LOVES YOU

Benson Cunningham
Dec 9, 2006

Chief of J.U.N.K.E.R. H.Q.
Thanks! Turned out it was an error in the caching mechanism of the app. If I'm going to have audio I need to grab those .mp3 tags.

Bitruder
Nov 29, 2003

Majoring in connect the dots and colouring
How do I determine which code goes in an NSView subclass and which code goes into an NSViewController subclass? If I make the delegate of my view my NSViewController subclass then I can just put it there, but if I just make my View an instantiation of my NSView subclass I feel like I could just put all my code for that view in there.

pokeyman
Nov 26, 2006

That elephant ate my entire platoon.

Bitruder posted:

How do I determine which code goes in an NSView subclass and which code goes into an NSViewController subclass? If I make the delegate of my view my NSViewController subclass then I can just put it there, but if I just make my View an instantiation of my NSView subclass I feel like I could just put all my code for that view in there.

Views are responsible for drawing themselves. Controllers are responsible for synchronizing the model and the view.

So if the code relates to something appearing on the screen, typically it'll go in the NSView subclass. Otherwise it'll go into the controller.

If that's still unclear (which wouldn't be surprising, it's a question with no agreed-upon answer), feel free to post an example or two and we can all point you in different directions.

NoDamage
Dec 2, 2000

NoDamage posted:

We actually just went through this experience porting Paprika from iOS to Mac...I'm currently writing up a blog post about the experience that I'll be able to post shortly. Suffice to say, your basic Objective-C and Foundation knowledge transfers quite well, but AppKit isn't nearly as clean to work with as UIKit. There are a lot of things you get 'for free' on iOS that you'll miss not having on Mac, and having to implement them yourself will slow you right down.

That said, the Mac App Store is pretty aces right now (and we probably wouldn't have attempted a Mac version if it didn't exist).
Here's that post: http://www.hindsightlabs.com/blog/2011/09/12/porting-paprika-from-ios-to-mac-a-technical-retrospective/

some kinda jackal
Feb 25, 2003

 
 
Thanks for writing that up, it's a lot of great insight. Also I'm only half familiar with all that CoreData material so it'll be good to know what to look out for when/if I ever get around to Mac development.

Simulated
Sep 28, 2001
Lowtax giveth, and Lowtax taketh away.
College Slice
It really seems like Apple needs to update AppKit to get with the times. They also need a way to let you run UIKit apps on the Mac.... I predict a Mac version of UIKit that makes it much easier to port.

pokeyman
Nov 26, 2006

That elephant ate my entire platoon.

Ender.uNF posted:

It really seems like Apple needs to update AppKit to get with the times. They also need a way to let you run UIKit apps on the Mac.... I predict a Mac version of UIKit that makes it much easier to port.

Two things:

1. Running UIKit Apps on the Mac is called "iPhone Simulator.app" (but I know what you mean)
2. See http://chameleonproject.org/

Toady
Jan 12, 2009

Ender.uNF posted:

It really seems like Apple needs to update AppKit to get with the times. They also need a way to let you run UIKit apps on the Mac.... I predict a Mac version of UIKit that makes it much easier to port.

Lion added a lot of nice things. UIKit is so centered around a touchscreen that it's hard to imagine it running on a Mac. iOS apps ported to the Mac without any changes usually feel awkward. I think they'll just keep updating AppKit and deprecating older APIs. I don't have such a problem with AppKit like some others do.

GazChap
Dec 4, 2004

I'm hungry. Feed me.
Odd one...

I've got a UITableView, in Grouped style. Two sections to it, the first one with just one row, and the second one has a dynamic number of rows depending on the length of an array passed in from my Application Delegate.

This is all working fine.

The section with the dynamic rows needs to allow the user to select a row, and have a checkmark appear on the row. Multiple rows can be selected, and if a selected row is ticked, it needs to be unticked.

The way I'm handling this is to have an NSMutableArray in the UITableViewController for storing selected indices, called - funnily enough - selectedIndices.

Everything is working perfectly, apart from one thing:

When I tap a cell, it doesn't appear to add the checkmark to the accessoryType. If I then tap another cell, the first cell gets a checkmark. If I tap another cell, the second row gets its checkmark, and so on and so forth.

On closer inspection on my device (as opposed to the simulator), it appears that when I tap a cell, it DOES get a checkmark, but it's a white checkmark rather than a dark checkmark. This then changes back to a dark checkmark when another cell is tapped.

I think it's the same white checkmark that appears on a cell while it's selected (with the blue gradient)

Any ideas what would be causing this?

In my cellForRowAtIndexPath method, I'm searching the selectedIndices array for the indexPath.row of the cell, and if it's found I'm setting the accessoryType to Checkmark, or None if it's not found.

In the didSelectRowAtIndexPath method, I'm checking the accessoryType of the selected cell, modifying it accordingly and then modifying my selectedIndices array to suit, before calling [tableView reloadData].

I can't find any info about this online, which suggests it's something I'm doing. Any ideas?

//edit: Never mind, I've put a deselectRowAtIndexPath call at the bottom of the didSelect... method, and it works fine now. Strikes me as odd that I have to explicitly do that, but there you go.

GazChap fucked around with this message at 15:00 on Sep 16, 2011

LP0 ON FIRE
Jan 25, 2006

beep boop
Kind of urgent.. I had an iPad enterprise application come back to haunt me from 6 months ago, exactly to this day. One of their iPads no longer launches the application because the provision expired, which according to what I thought, it shouldn't. The other devices are working fine, so something must have happened wrong along the way.

Since they're overseas, and they need it for a presentation tomorrow, I decided to make an online link download with a plist and application file in hopes it will work. I have an iPad here to test it on. This iPad however is not added to their device list on their development account, so I don't expect it to work. Yet, I DO expect it to download. After touching the link on iPad's Safari, and hitting OK on the confirmation box, the app looks like it's going to install, but it's just stuck on "Loading..."

It's been like this well over 10 minutes. So even though the app is 1.5 GB, I'd expect it to start showing a progress bar by now. I'm afraid it's something wrong with my plist, but everything looks correct. Maybe I left out a required field?

Over seas, this same exact thing is happening to their iPad when I gave them the download link.

*got rid of code to save you all some vertical space*

edit: Okay, I finally saw it jump to 1 pixels in width in the progress bar, and then 10 minutes later, 2 pixels, so it's doing something. But it still says "Loading..."

edit 2: Boss just emailed me... success. I was just freaking out. Still don't know how their provision expired, but oh well.

LP0 ON FIRE fucked around with this message at 03:35 on Sep 17, 2011

Funso Banjo
Dec 22, 2003

Does anyone have any experience fighting installous?

I have seen a drop off in sales since my best selling app hit installous. A drop off is expected, of course, at a certain point in an app's life, but this particular drop and the app appearing on installous is too much of a coincidence for me to just ignore it.

A couple of the hosting sites have removed the app after a simple email, but one in particular is basically saying I need to get a lawyer involved (my app sales are just about paying the bills, they will struggle to accomodate regular legal fees as well) to get it removed from their servers.

As a really small time self employed developer, I never though pirates would affect me :(

Funso Banjo fucked around with this message at 18:53 on Sep 19, 2011

Yodzilla
Apr 29, 2005

Now who looks even dumber?

Beef Witch
Is it possible to write an app that can display Powerpoint or Keynote files? I was asked this by a client and I really can't find an answer. My gut is telling me "no" since Apple offers their own Keynote application for only :10bux: on the app store but if anyone knows any more concrete details it's be much appreciated.

Carthag Tuek
Oct 15, 2005

Tider skal komme,
tider skal henrulle,
slægt skal følge slægters gang



Yodzilla posted:

Is it possible to write an app that can display Powerpoint or Keynote files? I was asked this by a client and I really can't find an answer. My gut is telling me "no" since Apple offers their own Keynote application for only :10bux: on the app store but if anyone knows any more concrete details it's be much appreciated.

I guess it should be possible in theory with Keynote files, as the APXL format appears to be documented:

http://developer.apple.com/appleapplications/keynote-apxl.html

The technote links in the end of that doc are broken but I guess they should be possible to find somewhere in their docs.

Yodzilla
Apr 29, 2005

Now who looks even dumber?

Beef Witch
Oh man last updated in 2005. Yikes.

I'm not sure that specific line of articles is going to help me too much but me Googling for those resources led me to this which is just about exactly what I need:

http://developer.apple.com/library/ios/#qa/qa1630/_index.html
http://www.buggyprogrammer.co.uk/2010/10/08/open-document-in-web-view-for-ios/

I didn't realize that WebViews can be used to display Keynote, Powerpoint, Word, and Excel files. With this knowledge I guess it should be fairly easy to create an app that displays multiple multimedia files back-to-back using only WebViews. I'll have to give this a shot.

LP0 ON FIRE
Jan 25, 2006

beep boop
I have a very curious question: When should I NOT use isEqualToString? I think I've been having intermittent issues when comparing an NSString with another NSString using isEqualToString, so I've stopped doing that and now use just a simple comparison like:

code:
NSString *teh = @"this";

NSString *whatev = @"this";

if(teh == whatev){
//stuff
}
It's now making me think I should only use isEqualToString I'm comparing an NSString with something that is not an NSString, but just some sort of string.

Carthag Tuek
Oct 15, 2005

Tider skal komme,
tider skal henrulle,
slægt skal følge slægters gang



NOG posted:

I have a very curious question: When should I NOT use isEqualToString? I think I've been having intermittent issues when comparing an NSString with another NSString using isEqualToString, so I've stopped doing that and now use just a simple comparison like:

code:
NSString *teh = @"this";

NSString *whatev = @"this";

if(teh == whatev){
//stuff
}
It's now making me think I should only use isEqualToString I'm comparing an NSString with something that is not an NSString, but just some sort of string.

a == b is instance equality -- the pointers point to the same exact object instance.

isEqualToString: means compare the contents of the NSString instances, so this is what you should use if you want to test if two NSStrings contain the same text.

I think the reason why the former might work in some cases is an effect of the Cocoa implementation of NSString, that is, immutable NSStrings with the same contents aren't allocated multiple times will be the same instance behind the scenes. This is not something you should count on.

some kinda jackal
Feb 25, 2003

 
 

Carthag posted:

immutable NSStrings with the same contents aren't allocated multiple times will be the same instance behind the scenes.

This seems really scary for some reason but I can't put my finger on why.

csammis
Aug 26, 2003

Mental Institution

Martytoof posted:

This seems really scary for some reason but I can't put my finger on why.

String interning in general?

Carthag Tuek
Oct 15, 2005

Tider skal komme,
tider skal henrulle,
slægt skal følge slægters gang



Martytoof posted:

This seems really scary for some reason but I can't put my finger on why.

It won't be a problem with the strings changing underneath you because someone else is changing a string elsewhere since they're immutable. But as seen above it can cause problems due to pointer equality if you aren't aware of it.

I might actually be remembering wrong, I think I read about it in Cocoa Design Patterns but I dont' have it handy right now, lemme google before I accidentally introduce a bunch of nonsense. (You should still use isEqualToString: though, that is the supported way of checking if two strings have the same contents).

Edit: I guess I was thinking of NSNumber which does have a pool. It doesn't appear NSStrings have it.

Carthag Tuek fucked around with this message at 22:57 on Sep 20, 2011

Toady
Jan 12, 2009

NOG posted:

I have a very curious question: When should I NOT use isEqualToString? I think I've been having intermittent issues when comparing an NSString with another NSString using isEqualToString

What intermittent issues are you having? You use -isEqualToString: when you know both objects are strings. As the documentation states, it's a little faster than -isEqual:, perhaps due to lack of type-checking.

You compare pointers when you want to know if they point to the same instance (i.e., an identity comparison). You use equality methods to compare the values of the objects, which may not be the same instance but still be considered equal. The difference between identity and equality in Cocoa is like a pair of dollar bills. They're equal in that they both represent $1 in currency, but they are not identical, because they have unique serial numbers.

Martytoof posted:

This seems really scary for some reason but I can't put my finger on why.

Conventionally, immutable objects also don't return new instances when you call -copy on them. They just retain and return themselves.

some kinda jackal
Feb 25, 2003

 
 

Carthag posted:

since they're immutable.

I think this is what I neglected to comprehend. Carry on :3:

carry on then
Jul 10, 2010

by VideoGames

(and can't post for 10 years!)

Hopefully this is a simple question, but I'm building a little (Mac) app to learn my way around the basic UI widgets. I've got a progress bar and button. When I press the button, I have it fill smoothly over 5 seconds. Right now, I'm doing this by incrementing the value by 1.0, then calling performSelector:withObject:afterDelay: like so:

code:
-(void)incrementProgressBar {
    if ([progressBar doubleValue] == 100.0) {
        [progressBar setDoubleValue:0.0];
        [startButton setEnabled:YES];
    }
    else {
        [progressBar incrementBy:1.0];
        [self performSelector:@selector(incrementProgressBar) withObject:self afterDelay:0.05];
    }
}
While this certainly works, I definitely feel like it's not ideal. Would an NSTimer be better here? I looked at the documentation, but the talk of threading may have obfuscated its applicability here; I was expecting something like a timer in C# which, when enabled, just fires an event (timerName_tick()) on the form it's attached to every interval milliseconds.

pokeyman
Nov 26, 2006

That elephant ate my entire platoon.

Toady posted:

What intermittent issues are you having? You use -isEqualToString: when you know both objects are strings. As the documentation states, it's a little faster than -isEqual:, perhaps due to lack of type-checking.

Why not just always use -isEqual:? I have a hard time believing that any type checking that goes on in NSString's implementation of isEqual: is remotely important to any application.

pokeyman
Nov 26, 2006

That elephant ate my entire platoon.

carry on then posted:

Hopefully this is a simple question, but I'm building a little (Mac) app to learn my way around the basic UI widgets. I've got a progress bar and button. When I press the button, I have it fill smoothly over 5 seconds. Right now, I'm doing this by incrementing the value by 1.0, then calling performSelector:withObject:afterDelay: like so:

code:
-(void)incrementProgressBar {
    if ([progressBar doubleValue] == 100.0) {
        [progressBar setDoubleValue:0.0];
        [startButton setEnabled:YES];
    }
    else {
        [progressBar incrementBy:1.0];
        [self performSelector:@selector(incrementProgressBar) withObject:self afterDelay:0.05];
    }
}
While this certainly works, I definitely feel like it's not ideal. Would an NSTimer be better here? I looked at the documentation, but the talk of threading may have obfuscated its applicability here; I was expecting something like a timer in C# which, when enabled, just fires an event (timerName_tick()) on the form it's attached to every interval milliseconds.

As far as I'm concerned there's nothing wrong with this approach. I mean, usually a progress bar is updated based on the progress of some task, so you wouldn't just arbitrarily increase it on a timer, but NSTimer isn't going to do anything special for you here.

edit: Though you should have "withObject:nil" as the selector you're calling has no arguments, so the docs tell you to leave it nil.

carry on then
Jul 10, 2010

by VideoGames

(and can't post for 10 years!)

pokeyman posted:

As far as I'm concerned there's nothing wrong with this approach. I mean, usually a progress bar is updated based on the progress of some task, so you wouldn't just arbitrarily increase it on a timer, but NSTimer isn't going to do anything special for you here.

edit: Though you should have "withObject:nil" as the selector you're calling has no arguments, so the docs tell you to leave it nil.

Thanks for the help. I did a bit more reading in the docs and got it working using a timer, namely scheduledTimerWithTimeInterval:target:selector:userInfo:repeats: and having the method it's invoking invalidate the timer when the progress bar is full. This does mean I need an instance variable for the timer, but then, that's how I'm used to it working elsewhere. I also see that if I want to pass arguments with the selector I'll have to make an NSInvocation but that seems pretty straightforward.

And I understand that the progress bar is only useful when backed by an actual task; I was interested in combining the use of a progress bar with the use of a repeated event. Of course, not even Apple themselves were above faking it occasionally.

carry on then fucked around with this message at 02:53 on Sep 21, 2011

LP0 ON FIRE
Jan 25, 2006

beep boop

Carthag posted:

I think the reason why the former might work in some cases is an effect of the Cocoa implementation of NSString, that is, immutable NSStrings with the same contents aren't allocated multiple times will be the same instance behind the scenes. This is not something you should count on.

Oh god. :psyduck: I've been changing the NSString values over the course of the program, and they are immutable? THAT'S the problem I think I'm having. Can I use NSMutableString with isEqualToString and everything should be okay, assuming my program is written correctly?


Toady posted:

What intermittent issues are you having? You use -isEqualToString: when you know both objects are strings. As the documentation states, it's a little faster than -isEqual:, perhaps due to lack of type-checking.

You compare pointers when you want to know if they point to the same instance (i.e., an identity comparison). You use equality methods to compare the values of the objects, which may not be the same instance but still be considered equal. The difference between identity and equality in Cocoa is like a pair of dollar bills. They're equal in that they both represent $1 in currency, but they are not identical, because they have unique serial numbers.

I set game character "states" in a way that makes it easy to identify what state they are in English, at a glance. If I just thought about this a little more than I'd realize I'm just comparing pointers. The intermittent problems I would have would be the character states would never change even though it was calling the methods that should do it when an event triggers a state change.

duck monster
Dec 15, 2004

Funso Banjo posted:

Does anyone have any experience fighting installous?

I have seen a drop off in sales since my best selling app hit installous. A drop off is expected, of course, at a certain point in an app's life, but this particular drop and the app appearing on installous is too much of a coincidence for me to just ignore it.

A couple of the hosting sites have removed the app after a simple email, but one in particular is basically saying I need to get a lawyer involved (my app sales are just about paying the bills, they will struggle to accomodate regular legal fees as well) to get it removed from their servers.

As a really small time self employed developer, I never though pirates would affect me :(

Last company I worked at got absolutely hosed when our app hit installous. I understand people warezing adobe or whatever. Zillion dollar company with zillion dollar product. Right or wrong, the economics of being poor-rear end and needing photoshop for a uni assignment are rationalizable. Its a dog act to pirate a $1 app when that $1 is directly coming out of a single persons meal for the night, especially when iphone app development gets seriously poverty line sometimes.

For what its worth, it could get worse. A while back I found our bands album on a whole bunch of online music stores that had no permission to be on there selling our album for like 70c and stuff. Seemed to perfectly co-inside with our sales crashing. When we tried to get them to take it down they basically said "Get your lawyer to contact us". So we reported it to the RIAA and never heard back about it. But eventually decided "gently caress it" and uploaded the whole drat thing to pirate bay, since the only way to compete with 70c is to give the loving thing away.

duck monster fucked around with this message at 19:05 on Sep 21, 2011

Carthag Tuek
Oct 15, 2005

Tider skal komme,
tider skal henrulle,
slægt skal følge slægters gang



NOG posted:

Oh god. :psyduck: I've been changing the NSString values over the course of the program, and they are immutable? THAT'S the problem I think I'm having. Can I use NSMutableString with isEqualToString and everything should be okay, assuming my program is written correctly?
Well that depends on what you mean by changing the strings. Since they're immutable (and thus unchangeable), I assume you're having the pointers point to new strings? That would work, for instance if they're @properties on some object, and you go object.property = @"newstring"; then that will indeed change the property and have the string be the new string object, so next time you check object.property, you will get @"newstring" back as expected.

NSMutableString (which can indeed use isEqualToString, it's a subclass of NSString after all) is for when you want to change a string, but maintain the same instance. NSString is for when you just discard the old string and replace it with a new one.

You should probably read through the Cocoa Core Competencies: http://developer.apple.com/library/ios/#DOCUMENTATION/General/Conceptual/DevPedia-CocoaCore/ObjectMutability.html

Toady
Jan 12, 2009

pokeyman posted:

Why not just always use -isEqual:? I have a hard time believing that any type checking that goes on in NSString's implementation of isEqual: is remotely important to any application.

Obviously, performance characteristics differ for each project, but if you already know they're both strings, I can't think of a reason not to use -isEqualToString:.

pokeyman
Nov 26, 2006

That elephant ate my entire platoon.

Toady posted:

Obviously, performance characteristics differ for each project, but if you already know they're both strings, I can't think of a reason not to use -isEqualToString:.

Maybe you're using strings for character states in a game and you decide that that concept should be its own class. Now you have to change every -isEqualToString: in your code.

If you're legitimately comparing strings (like a firstName property) then yeah, I have no problem. But tons of things can and are helpfully represented by strings when they really don't need to be. I'm even thinking of "constants" like NSKeyValueChangeNewKey; you can almost certainly use pointer equality there but to me you're just setting yourself up for weird future bugs.

Really, you're not much further ahead than saying "I know about string interning so why send -isEqualToString: when I can just compare pointers? Surely string interning will never change in its implementation, and I'll never pass in a mutable string, and I understand object-oriented programming." If the extra type checking is honestly a performance bottleneck, yeah, change it, but I'm not sure I see the value of always using -isEqualToString: up front. I'm not saying there is none, as I imagine there's a reason Xcode's autocomplete tries really hard to make you use it (among other things), but I can't see it.

bumnuts
Dec 10, 2004
mmm...crunchy

pokeyman posted:

I imagine there's a reason Xcode's autocomplete tries really hard to make you use it (among other things), but I can't see it.

If this is how we're supposed to choose, then he should definitely be using NSStream instead :)

wellwhoopdedooo
Nov 23, 2007

Pound Trooper!

pokeyman posted:

tons of things can and are helpfully represented by strings when they really don't need to be

oh man, not to get all coding horrors up in here, but jesus christ I could not possibly disagree more. If I had a nickel for every bug caused by someone deciding that the type system was like underpants and just got in the way, I'd have about the same amount of money as I do right now, because I essentially get a nickel every time somebody decides the type system is like underpants and just gets in the way.

pokeyman
Nov 26, 2006

That elephant ate my entire platoon.

wellwhoopdedooo posted:

oh man, not to get all coding horrors up in here, but jesus christ I could not possibly disagree more. If I had a nickel for every bug caused by someone deciding that the type system was like underpants and just got in the way, I'd have about the same amount of money as I do right now, because I essentially get a nickel every time somebody decides the type system is like underpants and just gets in the way.

No I'm totally with you. I had in mind things like using a pointer to a string as a constant (e.g. for the context pointer in KVO) so you can dereference it in the debugger to see what they mean. I'm a huge fan of using the type system, and there's generally no excuse for packing data into incomprehensible strings (hello type encodings).

CAT ON THE COUCH!!
Mar 30, 2009

Hark!! Yonder goon hast defamed a lady!! Fear not, CoTC to the rescue!!

lol ponytar
code:
<?xml version="1.0" encoding="UTF-8"?>
<entry xmlns="http://www.w3.org/2005/Atom">
  <content type="application/vnd.ctct+xml">
    <Contact xmlns="http://ws.constantcontact.com/ns/1.0/" id="http://api.constantcontact.com/ws/customers/XXXX/contacts/2">

...
Both the "content" and "Contact" nodes are null to me, I assume because of namespacing, but I'm not sure how to address them using NSXML.. Any ideas?

For example, both of these would be blank/null:

[xmlDoc rootElement] elementsForName:@"content"];
[xmlDoc rootElement] elementsForName:@"Contact"];

Am I on the right track here:

code:
NSXMLElement *subscriberDetailsXMLElement = [[NSXMLElement alloc] initWithXMLString:[getSubscriberRequest responseString] error:nil];
        NSXMLNode *ccxmlns = [NSXMLNode namespaceWithName:@"cc" stringValue:@"http://ws.constantcontact.com/ns/1.0/"];
        
        [subscriberDetailsXMLElement addNamespace:ccxmlns];

Toady
Jan 12, 2009

pokeyman posted:

Maybe you're using strings for character states in a game and you decide that that concept should be its own class. Now you have to change every -isEqualToString: in your code.

That should be relatively trivial since the compiler would let you know every point in the code where you tried to pass a non-string to -isEqualToString:.

quote:

If you're legitimately comparing strings (like a firstName property) then yeah, I have no problem. But tons of things can and are helpfully represented by strings when they really don't need to be. I'm even thinking of "constants" like NSKeyValueChangeNewKey; you can almost certainly use pointer equality there but to me you're just setting yourself up for weird future bugs.

Really, you're not much further ahead than saying "I know about string interning so why send -isEqualToString: when I can just compare pointers? Surely string interning will never change in its implementation, and I'll never pass in a mutable string, and I understand object-oriented programming."

I'm not following you on what pointer equality has to do with this, as these are value equality methods, and -isEqualToString: is functionally equivalent to passing a string to isEqual:. I think what you're saying is that constants like NSKeyValueChangeNewKey being literal strings is an implementation detail that shouldn't be relied on. However, using strings for dictionary keys, as well as notification names, is a Cocoa convention, and the types are publicly declared in the headers. If it was a non-public implementation detail, they would be typed id.

quote:

If the extra type checking is honestly a performance bottleneck, yeah, change it, but I'm not sure I see the value of always using -isEqualToString: up front. I'm not saying there is none, as I imagine there's a reason Xcode's autocomplete tries really hard to make you use it (among other things), but I can't see it.

Whatever performance improvement there may be is a bonus. Other advantages include expression of intent and static type checking.

pokeyman
Nov 26, 2006

That elephant ate my entire platoon.

Toady posted:

I'm not following you on what pointer equality has to do with this, as these are value equality methods, and -isEqualToString: is functionally equivalent to passing a string to isEqual:.

My point was that in both cases you might be assuming something that shouldn't be assumed, but will still work perfectly fine for now. I happily admit it was a poor comparison.

quote:

Whatever performance improvement there may be is a bonus. Other advantages include expression of intent and static type checking.

I'm not sure how "expression of intent" is helped; surely if you're sending isEqual: to an instance of (a subclass of) NSString, you're aware that you're checking for string equality. I guess static type checking is useful if you accidentally do [someString isEqualToString:anArray], though it seems like there's still some type checking going on in the implementation as that'll simply return NO.

I guess I'm entirely confused as to why -isEqualToString: and its array, dictionary, date, etc. cousins even exists as public methods. -isEqual: is overridden for each of those classes and gives an identical response.

Toady
Jan 12, 2009

pokeyman posted:

I'm not sure how "expression of intent" is helped; surely if you're sending isEqual: to an instance of (a subclass of) NSString, you're aware that you're checking for string equality. I guess static type checking is useful if you accidentally do [someString isEqualToString:anArray], though it seems like there's still some type checking going on in the implementation as that'll simply return NO.

I guess I'm entirely confused as to why -isEqualToString: and its array, dictionary, date, etc. cousins even exists as public methods. -isEqual: is overridden for each of those classes and gives an identical response.

-isEqual: takes an id and implies the possibility of comparing to non-strings. The method probably calls -isEqualToString: when passed a string, or calls the same internal functionality. In Cocotron, for example, both methods end up calling the inline function isEqualString(). -isEqual: must first do a class lookup, and if by construction your code will only ever compare strings, you can skip that check. Reasons for using the class-specific equality methods include faster performance, better expression of intent, and static type checking of the argument.

LP0 ON FIRE
Jan 25, 2006

beep boop

Carthag posted:

Well that depends on what you mean by changing the strings. Since they're immutable (and thus unchangeable), I assume you're having the pointers point to new strings? That would work, for instance if they're @properties on some object, and you go object.property = @"newstring"; then that will indeed change the property and have the string be the new string object, so next time you check object.property, you will get @"newstring" back as expected.

NSMutableString (which can indeed use isEqualToString, it's a subclass of NSString after all) is for when you want to change a string, but maintain the same instance. NSString is for when you just discard the old string and replace it with a new one.

You should probably read through the Cocoa Core Competencies: http://developer.apple.com/library/ios/#DOCUMENTATION/General/Conceptual/DevPedia-CocoaCore/ObjectMutability.html

Thanks for everyone's input. I stayed late last night and went through my entire project, replacing some NSStrings to NSMutableStrings, and changing every string comparison to isEqualToString. Works flawlessly so far.

I'll check out that documentation, since I don't seem to know everything about mutability.

Adbot
ADBOT LOVES YOU

CAT ON THE COUCH!!
Mar 30, 2009

Hark!! Yonder goon hast defamed a lady!! Fear not, CoTC to the rescue!!

lol ponytar
Let me clarify the problem:

code:
<?xml version="1.0" encoding="UTF-8"?>
<entry xmlns="http://www.w3.org/2005/Atom">
  <title type="text">Contact: [email]omgchead@gmail.com[/email]</title>
  <updated>2011-09-21T01:37:25.874Z</updated>
  <content type="application/vnd.ctct+xml">
    <Contact xmlns="http://ws.constantcontact.com/ns/1.0/" id="http://api.constantcontact.com/ws/customers/cheadd/contacts/2">
      <Status>Active</Status>
    </Contact>
  </content>
</entry>
NSLog(@"%d", [[subscriberDetailsXML elementsForName:@"updated"] count]);
Outputs: 1

NSLog(@"%d", [[subscriberDetailsXML elementsForName:@"content"] count]);
Outputs: 0

NSLog(@"%d", [[subscriberDetailsXML elementsForName:@"Contact"] count]);
Outputs: 0

NSLog(@"%d", [[subscriberDetailsXML elementsForLocalName:@"Contact" URI:@"http://ws.constantcontact.com/ns/1.0/"] count]);
Outputs: 0

  • 1
  • 2
  • 3
  • 4
  • 5
  • Post
  • Reply